весь файл из ifstream >> string
Вопрос вроде простой, но туплю
Как прочитать весь файл из ifstream в один большой string?
Самый простой стандартный способ?
(Если просто ifs >> s то читается строка до первого разделителя между словами...)
Заранее спасибо.
Re: весь файл из ifstream >> string
Здравствуйте, Ignoramus, Вы писали:
I>Вопрос вроде простой, но туплю
I>Как прочитать весь файл из ifstream в один большой string?
I>Самый простой стандартный способ?
I>(Если просто ifs >> s то читается строка до первого разделителя между словами...)
I>Заранее спасибо.
string s;
copy(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>(), back_inserter(s));
Re: весь файл из ifstream >> string
Здравствуйте, Ignoramus, Вы писали:
fstream file("c:\\1.txt" );
string str;
copy(
istream_iterator<char >(file),
istream_iterator<char >(),
insert_iterator<string>(str,str.begin()));
Re: весь файл из ifstream >> string
От:
zelyony
Дата: 23.05.05 12:02
Оценка:
file.seekg( 0, ios_base::end);
pos_type len = file.tellg();
file.seekg( 0);
str.resize( len);
file.read( (char*)str.data(), len); // нехорошо
Posted via RSDN NNTP Server 1.9
Re: весь файл из ifstream >> string
От:
Chorkov
Дата: 23.05.05 12:09
Оценка:
Здравствуйте, Ignoramus, Вы писали:
string s;
ifstream inp("test.txt" );
getline(inp, s, '\0' );
Re: весь файл из ifstream >> string
От:
ssm
Дата: 23.05.05 12:18
Оценка:
Здравствуйте, Ignoramus, Вы писали:
I>Как прочитать весь файл из ifstream в один большой string?
I>Самый простой стандартный способ?
так делают парни из boost:
void load_file(std::string& s, std::istream& is)
{
s.erase();
if (is.bad()) return ;
//
// attempt to grow string buffer to match file size,
// this doesn't always work...
s.reserve(is.rdbuf()->in_avail());
char c;
while (is.get(c))
{
// use logarithmic growth stategy, in case
// in_avail (above) returned zero:
if (s.capacity() == s.size())
s.reserve(s.capacity() * 3);
s.append(1, c);
}
}
Re: весь файл из ifstream >> string
Здравствуйте, Ignoramus, Вы писали:
I>Как прочитать весь файл из ifstream в один большой string?
Обединяя всё вышенаписанное в нормальный вариант:
typedef std::istream_iterator<char > IIC;
file.seekg( 0, std::ios_base::end);
std::fstream::pos_type size = file.tellg();
file.seekg( 0);
//теперь так
std::string str_file;
str_file.reserve(size);
std::copy(IIC(file), IIC(), std::back_inserter(str_file));
Не перебивайте меня, когда я вас перебиваю
Re[2]: весь файл из ifstream >> string
От:
Erop
Дата: 24.05.05 04:39
Оценка:
Здравствуйте, Valodzka, Вы писали:
V>V>typedef std::istream_iterator<char > IIC;
V>file.seekg( 0, std::ios_base::end);
V>std::fstream::pos_type size = file.tellg();
V>file.seekg( 0);
V>//теперь так
V>std::string str_file;
V>str_file.reserve(size);
V>std::copy(IIC(file), IIC(), std::back_inserter(str_file));
V>
А что случится, если в файле встретится байт '\0'?
Я так понимаю, что такой байт в строчку добавлять нельзя?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: весь файл из ifstream >> string
"Ignoramus" <18039@users.rsdn.ru> wrote in message
news:1186457@news.rsdn.ru
> Вопрос вроде простой, но туплю
>
> Как прочитать весь файл из ifstream в один большой string?
>
> Самый простой стандартный способ?
Например, такой (очень простой, не правда ли?):
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main(int argc, char * argv[])
{
ifstream in(argv[1]);
ostringstream out;
out << in.rdbuf(); // <---------
cout << out.str();
}Posted via RSDN NNTP Server 1.9
Re: весь файл из ifstream >> string
От:
Аноним
Дата: 24.05.05 07:04
Оценка:
1 (1)
+1
Здравствуйте, Ignoramus, Вы писали:
I>Вопрос вроде простой, но туплю
I>Как прочитать весь файл из ifstream в один большой string?
I>Самый простой стандартный способ?
I>(Если просто ifs >> s то читается строка до первого разделителя между словами...)
I>Заранее спасибо.
ifstream file("some.txt" );
typedef istreambuf_iterator<char > iter;
string str( (iter(file)), iter() );
Re[3]: весь файл из ifstream >> string
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Valodzka, Вы писали:
V>>V>>typedef std::istream_iterator<char > IIC;
V>>file.seekg( 0, std::ios_base::end);
V>>std::fstream::pos_type size = file.tellg();
V>>file.seekg( 0);
V>>//теперь так
V>>std::string str_file;
V>>str_file.reserve(size);
V>>std::copy(IIC(file), IIC(), std::back_inserter(str_file));
V>>
E>А что случится, если в файле встретится байт '\0'?
E>Я так понимаю, что такой байт в строчку добавлять нельзя?
А почему в std::string нельзя '\0' добавить? В чем проблема-то?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer :
<микро> Агентно-ориентированное программирование на C++.
От:
ssm
Дата: 24.05.05 09:30
Оценка:
6 (3)
Здравствуйте, Ignoramus, Вы писали:
Сравнил скорость всех предложенных методов, в конце постинга сабж.
Сразу оговорюсь, что на корректность теста я не претендую, просто было интерестно померять время в конкретном случае, а именно взял текстовый файл на 6,5 метров. MSVC 7.1 /O2
Вот тестец(оставил все, как было в оригинальных постах):
#include <fstream>
#include <algorithm>
#include <string>
#include <sstream>
using namespace std;
void readFile1(const char *fileName)
{
std::ifstream ifs(fileName, std::ios::binary);
std::string s;
copy(istreambuf_iterator<char >(ifs), istreambuf_iterator<char >(), back_inserter(s));
std::cout << " " << s.length() << " " ;
}
void readFile2(const char *fileName)
{
std::ifstream file(fileName, std::ios::binary);
std::string str;
std::copy(
istream_iterator<char >(file),
istream_iterator<char >(),
insert_iterator<string>(str,str.begin()));
std::cout << " " << str.length() << " " ;
}
void readFile3(const char *fileName)
{
std::ifstream file(fileName, std::ios::binary);
string str;
file.seekg( 0, ios_base::end);
std::ifstream::pos_type len = file.tellg();
file.seekg( 0);
str.resize( len);
file.read( (char *)str.data(), len);
std::cout << " " << str.length() << " " ;
}
void readFile4(const char *fileName)
{
string s;
ifstream inp(fileName, std::ios::binary);
getline(inp, s, '\0' );
std::cout << " " << s.length() << " " ;
}
void readFile5(const char *fileName)
{
string s;
ifstream is(fileName, std::ios::binary);
//
// attempt to grow string buffer to match file size,
// this doesn't always work...
s.reserve(is.rdbuf()->in_avail());
char c;
while (is.get(c))
{
// use logarithmic growth stategy, in case
// in_avail (above) returned zero:
if (s.capacity() == s.size())
s.reserve(s.capacity() * 3);
s.append(1, c);
}
std::cout << " " << s.length() << " " ;
}
void readFile6(const char *fileName)
{
typedef std::istream_iterator<char > IIC;
std::ifstream file(fileName, std::ios::binary);
file.seekg( 0, std::ios_base::end);
std::fstream::pos_type size = file.tellg();
file.seekg( 0);
std::string str_file;
str_file.reserve(size);
std::copy(IIC(file), IIC(), std::back_inserter(str_file));
std::cout << " " << str_file.length() << " " ;
}
void readFile7(const char *fileName)
{
std::ifstream in(fileName, std::ios::binary);
ostringstream out;
out << in.rdbuf();
string s;
out.str().swap(s);
std::cout << " " << s.length() << " " ;
}
typedef void (*PF)(const char *);
class FReadFile
{
public :
FReadFile(const char *fileName)
: fileName(fileName)
{
}
void operator ()(PF pf) const
{
pf(fileName);
}
private :
const char *fileName;
};
int main()
{
const size_t readersCount = 7;
PF readers[readersCount] = {
readFile1, readFile2, readFile3,
readFile4, readFile5, readFile6,
readFile7
};
FReadFile func("c:\\temp\\prof\\test.txt" );
for (int i = 0; i < 10; ++i)
{
std::for_each(readers, readers + readersCount, func);
std::cout << i << "\n" ;
}
}
собственно сабж.
"Method Name","% in Method","% with Children","Called","Average"
"readFile5", "43,9", "44,0", "10", "3836250,8"
"readFile2", "17,5", "17,6", "10", "1526903,1"
"readFile6", "14,9", "15,0", "10", "1304416,2"
"readFile1", "11,6", "11,8", "10", "1015325,8"
"readFile4", "7,1", "7,3", "10", "622452,2"
"readFile7", "3,6", "3,8", "10", "317294,6"
"readFile3", "0,3", "0,4", "10", "27201,5"
выводы делать не возьмусь, замечу только, что бустовская попытка оптимизации окончилась фиаско
для меня фаворит readFile7, хотя конечно readFile3 делает всех, но ИМХО на больших размерах файлов может быть эффективней читать порциями, а не все одной сарделькой.
Здравствуйте, ssm, Вы писали:
Так ведь:
ssm>ssm>void readFile3(const char *fileName)
ssm>{
ssm> std::ifstream file(fileName, std::ios::binary);
ssm> string str;
ssm> file.seekg( 0, ios_base::end);
ssm> std::ifstream::pos_type len = file.tellg();
ssm> file.seekg( 0);
ssm> str.resize( len);
ssm> file.read( (char *)str.data(), len);
ssm> std::cout << " " << str.length() << " " ;
ssm>}
ssm>
некорректен.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer :
<микро> Агентно-ориентированное программирование на C++.
От:
ssm
Дата: 24.05.05 09:49
Оценка:
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, ssm, Вы писали:
E>Так ведь:
ssm>>ssm>>void readFile3(const char *fileName)
ssm>>
E>некорректен.
"оставил все, как было в оригинальных постах"
Здравствуйте, ssm, Вы писали:
ssm>Здравствуйте, eao197, Вы писали:
E>>Здравствуйте, ssm, Вы писали:
E>>Так ведь:
ssm>>>ssm>>>void readFile3(const char *fileName)
ssm>>>
E>>некорректен.
ssm>ssm>"оставил все, как было в оригинальных постах"
А если бы завалилось все?
Кстати, а как поменяются результаты измерений, если из каждой функции убрать финальную std::cout << " " << s.length()... ?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer :
<микро> Агентно-ориентированное программирование на C++.
От:
zelyony
Дата: 24.05.05 09:57
Оценка:
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, ssm, Вы писали:
E>Так ведь:
ssm>>ssm>>void readFile3(const char *fileName)
ssm>>{
ssm>> std::ifstream file(fileName, std::ios::binary);
ssm>> string str;
ssm>> file.seekg( 0, ios_base::end);
ssm>> std::ifstream::pos_type len = file.tellg();
ssm>> file.seekg( 0);
ssm>> str.resize( len);
ssm>> file.read( (char *)str.data(), len); //(*)
ssm>> std::cout << " " << str.length() << " " ;
ssm>>}
ssm>>
E>некорректен.
а так?
file.read( &str[0], len); //(*)
Здравствуйте, zelyony, Вы писали:
Z>Здравствуйте, eao197, Вы писали:
E>>Здравствуйте, ssm, Вы писали:
E>>Так ведь:
ssm>>>ssm>>>void readFile3(const char *fileName)
ssm>>>{
ssm>>> std::ifstream file(fileName, std::ios::binary);
ssm>>> string str;
ssm>>> file.seekg( 0, ios_base::end);
ssm>>> std::ifstream::pos_type len = file.tellg();
ssm>>> file.seekg( 0);
ssm>>> str.resize( len);
ssm>>> file.read( (char *)str.data(), len); //(*)
ssm>>> std::cout << " " << str.length() << " " ;
ssm>>>}
ssm>>>
E>>некорректен.
Z>а так?
Z>Z> file.read( &str[0], len); //(*)
Z>
Имхо, это тоже самое.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer :
<микро> Агентно-ориентированное программирование на C++.
От:
ssm
Дата: 24.05.05 10:15
Оценка:
Здравствуйте, eao197, Вы писали:
E>А если бы завалилось все?
но мы ведь не из робкого десятка
E>Кстати, а как поменяются результаты измерений, если из каждой функции убрать финальную std::cout << " " << s.length()... ?
никак
размер файла все-таки 6,5 метров
Тоже решил пойти по следам ssm.
Собрал вот такую программку:
#include <iostream>
#include <iterator>
#include <fstream>
#include <algorithm>
#include <functional>
#include <string>
#include <sstream>
#include <ctime>
#include <map>
using namespace std;
void readFile1(const char *fileName)
{
std::ifstream ifs(fileName, std::ios::binary);
std::string s;
copy(istreambuf_iterator<char >(ifs), istreambuf_iterator<char >(), back_inserter(s));
std::cout << " " << s.length() << " " ;
}
void readFile2(const char *fileName)
{
std::ifstream file(fileName, std::ios::binary);
std::string str;
std::copy(
istream_iterator<char >(file),
istream_iterator<char >(),
insert_iterator<string>(str,str.begin()));
std::cout << " " << str.length() << " " ;
}
void readFile4(const char *fileName)
{
string s;
ifstream inp(fileName, std::ios::binary);
getline(inp, s, '\0' );
std::cout << " " << s.length() << " " ;
}
void readFile5(const char *fileName)
{
string s;
ifstream is(fileName, std::ios::binary);
//
// attempt to grow string buffer to match file size,
// this doesn't always work...
s.reserve(is.rdbuf()->in_avail());
char c;
while (is.get(c))
{
// use logarithmic growth stategy, in case
// in_avail (above) returned zero:
if (s.capacity() == s.size())
s.reserve(s.capacity() * 3);
s.append(1, c);
}
std::cout << " " << s.length() << " " ;
}
void readFile6(const char *fileName)
{
typedef std::istream_iterator<char > IIC;
std::ifstream file(fileName, std::ios::binary);
file.seekg( 0, std::ios_base::end);
std::fstream::pos_type size = file.tellg();
file.seekg( 0);
std::string str_file;
str_file.reserve(size);
std::copy(IIC(file), IIC(), std::back_inserter(str_file));
std::cout << " " << str_file.length() << " " ;
}
void readFile7(const char *fileName)
{
std::ifstream in(fileName, std::ios::binary);
ostringstream out;
out << in.rdbuf();
string s;
out.str().swap(s);
std::cout << " " << s.length() << " " ;
}
typedef void (*PF)(const char *);
typedef std::map< std::string, PF > func_map_t;
struct meter_t
: public std::unary_function< func_map_t::value_type, void >
{
int m_argc;
char ** m_argv;
meter_t( int argc, char ** argv )
: m_argc( argc )
, m_argv( argv )
{}
result_type
operator ()( argument_type a )
{
std::cout << a.first << " " << std::flush;
std::clock_t start = std::clock();
for ( int i = 1; i < m_argc; ++i )
(*a.second)( m_argv[ i ] );
std::clock_t finish = std::clock();
std::cout << "duration: " << double ( finish - start ) / CLOCKS_PER_SEC
<< std::endl;
}
};
int main( int argc, char ** argv )
{
func_map_t readers;
readers[ "readFile1" ] = &readFile1;
readers[ "readFile2" ] = &readFile2;
readers[ "readFile4" ] = &readFile4;
readers[ "readFile5" ] = &readFile5;
readers[ "readFile6" ] = &readFile6;
readers[ "readFile7" ] = &readFile7;
std::for_each(
readers.begin(), readers.end(),
meter_t( argc, argv ) );
}
Тестировал на файлах от ~35Mb до ~50Mb. Забавно, что readFile2, readFile4, readFile6 выдают в результате неправильные размеры
На Visual С++ 7.1 получил:
readFile1 50996600 46676172 40532459 40480453 36657475 duration: 22.92
readFile2 49827578 45636872 39624753 39557524 35823658 duration: 36.843
readFile4 6 5 3 3 5 duration: 0.047
readFile5 50996600 46676172 40532459 40480453 36657475 duration: 25.655
readFile6 49827578 45636872 39624753 39557524 35823658 duration: 35.42
readFile7 50996600 46676172 40532459 40480453 36657475 duration: 14.984
На Borland C++ 5.6:
readFile1 50996600 46676172 40532459 40480453 36657475 duration: 17.203
readFile2 49827578 45636872 39624753 39557524 35823658 duration: 50.234
readFile4 6 5 3 3 5 duration: 0.016
readFile5 50996600 46676172 40532459 40480453 36657475 duration: 34.938
readFile6 49827578 45636872 39624753 39557524 35823658 duration: 62.593
readFile7 50996600 46676172 40532459 40480453 36657475 duration: 23.282
На MinGW C++ (3.2.3 20030504-1):
readFile1 50996600 46676172 40532459 40480453 36657475 duration: 34.9
readFile2 49827578 45636872 39624753 39557524 35823658 duration: 62.562
readFile4 6 5 3 3 5 duration: 0.157
readFile5 50996600 46676172 40532459 40480453 36657475 duration: 55.983
readFile6 49827578 45636872 39624753 39557524 35823658 duration: 59.307
readFile7 50996600 46676172 40532459 40480453 36657475 duration: 14.47
Еще под Linux-ом осталось подсчитать.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer :
<микро> Агентно-ориентированное программирование на C++.
Re[3]: весь файл из ifstream >> string
От:
Valodzka
Дата: 24.05.05 10:53
Оценка:
Здравствуйте, Erop, Вы писали:
E>А что случится, если в файле встретится байт '\0'?
E>Я так понимаю, что такой байт в строчку добавлять нельзя?
Точно где это написано не помню, но по стандарту std::string должен корректно обрабатывать любые символы, в том числе '\0'
Не перебивайте меня, когда я вас перебиваю
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить