How do I read a file into a std::string
, i.e., read the whole file at once?
Text or binary mode should be specified by the caller. The solution should b
An updated function which builds upon CTT's solution:
#include
#include
#include
#include
std::string readfile(const std::string_view path, bool binaryMode = true)
{
std::ios::openmode openmode = std::ios::in;
if(binaryMode)
{
openmode |= std::ios::binary;
}
std::ifstream ifs(path.data(), openmode);
ifs.ignore(std::numeric_limits::max());
std::string data(ifs.gcount(), 0);
ifs.seekg(0);
ifs.read(data.data(), data.size());
return data;
}
There are two important differences:
tellg()
is not guaranteed to return the offset in bytes since the beginning of the file. Instead, as Puzomor Croatia pointed out, it's more of a token which can be used within the fstream calls. gcount()
however does return the amount of unformatted bytes last extracted. We therefore open the file, extract and discard all of its contents with ignore()
to get the size of the file, and construct the output string based on that.
Secondly, we avoid having to copy the data of the file from a std::vector
to a std::string
by writing to the string directly.
In terms of performance, this should be the absolute fastest, allocating the appropriate sized string ahead of time and calling read()
once. As an interesting fact, using ignore()
and countg()
instead of ate
and tellg()
on gcc compiles down to almost the same thing, bit by bit.