Home > Back-end >  Does std::string needs explicit resizing or does it handles resizing itself?
Does std::string needs explicit resizing or does it handles resizing itself?

Time:03-30

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);
  • Related