0

Is there a one-liner to read the contents of a (not very big) text file into a string?

The shortest I've found:

#include <string>
#include <fstream>
#include <streambuf>

std::ifstream t("file.txt");
std::string str((std::istreambuf_iterator<char>(t)),
                 std::istreambuf_iterator<char>());

(For large files note that it is extremely inefficient solution since it has to reallocate the buffer after each new character it reads from the stream.)

credit: @Tyler McHenry Read whole ASCII file into C++ std::string

Community
  • 1
  • 1
quimnuss
  • 1,383
  • 15
  • 34

2 Answers2

7

You can do it in a single statement:

std::string str(std::istreambuf_iterator<char>(std::ifstream("file.txt").rdbuf()), std::istreambuf_iterator<char>());

Whether that's a one-liner depends how big your monitor is...

Steve Jessop
  • 257,525
  • 32
  • 431
  • 672
3

please note that it is not suitable for large files

Instead of "being not suitable for large files" I would rather say that it is extremely inefficient solution since it has to repeatedly reallocate the buffer as new characters are being read from the stream.

Also note that number of lines of your code is in this case one of the metrics that you should pay least attention to. Once you have ifstream object (name of which should be more meaningful than t),
you should check its state, whether it is_open() and much more reasonable way of reading from it seems to be this kind of approach:

// obtain the size of the input file stream:
file.seekg(0, std::ios::end);
std::streampos fileSize = file.tellg();
file.seekg(0, std::ios::beg);

// read the file into the string:
std::string fileData(fileSize);
file.read(&fileData[0], fileSize);

"Less lines of code" doesn't always mean "better".

LihO
  • 37,789
  • 9
  • 89
  • 156
  • String doesn't expand exponentially? – Lightness Races in Orbit Mar 27 '13 at 15:22
  • @LightnessRacesinOrbit: I'm actually not sure, I've edited that line. I just have quite unpleasant experiences with reading file contents that way (although I've always used `std::vector` before, not `std::string`) – LihO Mar 27 '13 at 15:29
  • @LightnessRacesinOrbit: In case of exponential expansion, I would be worried about memory requirements of that solution than since sometimes it might lead to almost twice as much memory as needed being allocated. – LihO Mar 27 '13 at 15:31
  • The two-iterator constructor of `vector` is constrained to do at most `O(log N)` reallocations (none if the iterator is a ForwardIterator or better, which of course this one isn't), so it must increase exponentially. I don't see that requirement for `basic_string`, though. – Steve Jessop Mar 27 '13 at 15:33