0

This may be trivial, but I'm new to C++ and an getting confused here.

I have the method:

bool load_database_file( const std::string& filename, std::string& contents ) {

    std::ifstream is (filename, std::ifstream::binary);
    if (is) {
        // get length of file:
        is.seekg (0, is.end);
        int length = (int)is.tellg();
        is.seekg (0, is.beg);

        char * buffer = new char [length];

        std::cout << "Reading " << length << " characters... ";
        // read data as a block:
        is.read (buffer, length);

        if (is)
            std::cout << "all characters read successfully.";
        else
            std::cout << "error: only " << is.gcount() << " could be read";
        is.close();

        // ...buffer contains the entire file...

        std::string str(buffer);
        contents = str;

        delete[] buffer;
    }

    return true ;  
}

where I would like to read a file and assign it's contents to contents so that it can be read by the calling function.

My issue is that after this function is run, I see that only the first character of buffer was copied to contents.

How can I copy/convert the entire contents of buffer (a char *) to contents (a std::string).

Brett
  • 10,971
  • 27
  • 114
  • 198
  • 1
    Did you get the example from [here](http://www.cplusplus.com/reference/istream/istream/tellg/)? Please note that in this case your length is one too short to hold a zero-terminated string, and second that you don't zero-terminate your string before assigning it to `std::string`. – MicroVirus Jul 07 '14 at 17:53
  • What encoding is the file using? – Mooing Duck Jul 07 '14 at 17:53
  • @MicroVirus I got the example from here: http://www.cplusplus.com/reference/istream/istream/read/ – Brett Jul 07 '14 at 17:55
  • Then my remark holds true. David Schwartz's answer circumvents the issue. – MicroVirus Jul 07 '14 at 17:57
  • `char * buffer = new char [length];` Replace that with this: `std::vector buffer(length);` – PaulMcKenzie Jul 07 '14 at 18:01

1 Answers1

2
    std::string str(buffer);

Should be:

    std::string str(buffer, buffer+length);

Otherwise, how can the constructor know how many bytes to allocate/copy?

By the way, your code is needlessly clumsy. Why not read directly into the string's buffer rather than using a separate buffer that you have to allocate and free just to hold the data before you allocate another buffer?

Soumadeep Saha
  • 326
  • 1
  • 13
David Schwartz
  • 166,415
  • 16
  • 184
  • 259
  • 3
    Because before C++11 there was no guarantee of contiguity in `std::string`? And, actually, because the OP _should_ be reading in a loop, to ensure he has all the characters. You don't know how many `read` invocations that'll take. A buffer inside a loop is the conventional way to handle that. – Lightness Races in Orbit Jul 07 '14 at 18:00