Archived

This topic is now archived and is closed to further replies.

daerid

Quickest way to load a file into a std::string?

Recommended Posts

I seem to remember somebody posting a way of doing this in a couple lines of code using a std::ifstream, a std::istreambuf_iterator, and a std::string Any takers?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
stringstream stream;
copy(istream_iterator<char>(fin), istream_iterator<char>(), ostream_iterator<char>(stream));
string bleh = stream.str();

stringstream::str() returns by value though, so it''s not so quick after all. The fastest way is to first use seek() to find how large the file is, allocate a string large enough and then use copy:

string bleh;
bleh.reserve(filesize);
copy(istream_iterator<char>(fin), istream_iterator<char>(), back_inserter(bleh));

A bit faster still may be this option:

string bleh;
bleh.resize(filesize);
copy(istream_iterator<char>(fin), istream_iterator<char>(), &bleh[0]);

But it has the unfortunate property of assigning values to bleh right before they are overwritten.

Share this post


Link to post
Share on other sites
Here's another one of my favorites - reads in a text file of integers, separated by whitespace, and prints out a sorted text file of those same integers, separated by new lines.

multiset<int> myvec(istream_buffer<int>(ifstream("numbers.txt")),istream_buffer());
copy(myvec.begin(),myvec.end(),ostream_iterator<int>(ofstream("sorted.txt"),"\n"));

As for tutorials, well, i'm not really sure where i picked up most of this. There's a book on the stl by austern(or musser) that's quite good.

edit: added paren

[edited by - sjelkjd on August 6, 2003 3:52:00 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
stringstream stream;
copy(istream_iterator(fin), istream_iterator(), ostream_iterator(stream));
string bleh = stream.str();


This will eat whitespace, whereas istreambuf_iterator will not.

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
A bit faster still may be this option:

string bleh;
bleh.resize(filesize);
copy(istream_iterator(fin), istream_iterator(), &bleh[0]);


That &bleh[0] isn''t likely to do anything good as far as correct code is concerned (doesn''t mean it won''t work, of course). You''d better use something like bleh.begin().

Share this post


Link to post
Share on other sites
quote:
Original post by sjelkjd

string myfile(istreambuf_iterator<char>(ifstream("file.txt")),istreambuf_iterator<char>());



So beautiful... *snif*

Can you tell me what happens when the file open fails?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by mputters
That &bleh[0] isn''t likely to do anything good as far as correct code is concerned (doesn''t mean it won''t work, of course). You''d better use something like bleh.begin().
Since this is legal:

bleh[0] = 3;

the character must be returned by reference. Thus taking it''s address is correct there.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
String iterators are not guaranteed to be implemented as character pointers though. If the STL implementation doesn''t implement strings as character arrays, then this might not work.

Share this post


Link to post
Share on other sites
quote:
Original post by Jedyte Can you tell me what happens when the file open fails?


Then the istream_iterator is basically the same as doing istream_iterator() - it''s empty. The string gets initialized to a blank string.

Share this post


Link to post
Share on other sites
quote:
Original post by mputters
quote:
Original post by Anonymous Poster
A bit faster still may be this option:

string bleh;
bleh.resize(filesize);
copy(istream_iterator(fin), istream_iterator(), &bleh[0]);


That &bleh[0] isn't likely to do anything good as far as correct code is concerned (doesn't mean it won't work, of course). You'd better use something like bleh.begin().



&bleh[0] is valid for a vector, if you use bleh.begin() then you have to say &*bleh.begin() (the so-called iterator deferencing operator) to be portable.

[edited by - Magmai Kai Holmlor on August 6, 2003 12:11:25 AM]

Share this post


Link to post
Share on other sites