I am trying to write a std::string in a file and then reading it back. Why do i need to resize the string while reading back the text (see the commented line below while reading back the string)? Doesn't the string handles its size automatically?
#include <iostream>
#include <fstream>
int main()
{
{
std::ofstream ofile("c:\\out.txt", std::ios_base::binary);
if (!ofile.is_open())
{
std::cout << "Failed to open the file";
return 1;
}
std::string s = "Hello World";
try
{
ofile.write(s.data(), s.size());
if (ofile.fail())
{
std::cout << "Failed to write the file";
return 1;
}
}
catch (std::ios_base::failure& e)
{
std::cout << e.what();
}
ofile.close();
}
{
std::ifstream ifile("c:\\out.txt", std::ios_base::binary);
if (!ifile.is_open())
{
std::cout << "Unable to open input file";
return 1;
}
ifile.seekg(0, std::ios::end);
auto length = ifile.tellg();
ifile.seekg(0, std::ios::beg);
std::string outstr;
//outstr.resize(length);
try
{
ifile.read(reinterpret_cast<char*>(&outstr.front()), length);
}
catch (std::ios_base::failure& e)
{
std::cout << e.what();
}
std::cout << outstr;
}
return 0;
}
CodePudding user response:
The parameters of istream::read
specify a buffer, not a string. Therefore, the function cannot know that there is an object that could theoretically be instructed to resize storage. For this reason, the caller has to do the resizing.
CodePudding user response:
After C 11, std::string
is guaranteed to have contiguous memory buffer.
Quoted from cppreference
The elements of a basic_string are stored contiguously
So you may use this characteristic of std::string
to use it as a buffer as long as you have std::string
reserve the size you need. Note that std::string
won't allocate the buffer for you while using its underlying buffer.
However I'd suggest to use std::string
as is instead of using it as a raw buffer. So you don't have to resize it manually. Eg: using std::stringstream
to take the buffer from std::ifstream
// ... open ifstream ifile...
std::stringstream ss;
ss << ifile.rdbuf();
// Use ss.str() to get `std::string`
If you really wants to use std::string
as raw buffer, you need to reserve the size beforehand.
// ...
std::string outstr(length, ' '); // or call `outstr.resize()` after
ifile.read(&outstr[0]), length);