#Writing and reading std::string to file

1 messages · Page 1 of 1 (latest)

versed canyon
#

I am trying to write a std::vector<std::string> to file and read it out again.

The writing looks like this:

std::ifstream f(fname, std::ios::binary);

num = _resultColumnNames.size();
f.write(reinterpret_cast<const char*>(&num), sizeof(size_t));
for (size_t i = 0; i < num; i++) {
  std::string resultColumnName = _resultColumnNames[i];
  size_t resultColumnNameLength = resultColumnName.length();
  f.write(reinterpret_cast<const char*>(&resultColumnNameLength), sizeof(size_t));
  f.write(resultColumnName.c_str(), resultColumnNameLength);
}
  1. Get the vector size to know how many std::string to write
  2. Write the size to file
  3. For every std::string write its length and characters to file

The reading looks like this:

f.seekg(posResultColumnNames);
for (size_t i = 0; i < numResultColumnNames; i++) {
  size_t resultColumnNameLength;
  std::string resultColumnName;
    
  f.read(reinterpret_cast<char*>(&resultColumnNameLength), sizeof(size_t));
  resultColumnName.reserve(resultColumnNameLength);
    
  f.read(reinterpret_cast<char*>(&resultColumnName[0]), resultColumnNameLength);
    
  LOG(INFO) << "[GEOMCACHE] resultColumnNameLength: " << resultColumnNameLength;
  LOG(INFO) << "[GEOMCACHE] resultColumnName: " << resultColumnName;
}
  1. Seek to where the data begins
  2. Read the std::string length
  3. Reserve that many characters for the std::string
  4. Read the characters

The length of the std::string is properly read for every std::string, but the std::string itself is always empty. I don't know if it already goes wrong when writing the data or if it is only a reading problem. Does someone know why this doesn't work? Thank you!

worthy viperBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

subtle gull
#

You need to use ::Resize instead of ::Reserve. You cant access an index that is beyond ::Size of the string. ::Reserve doesnt change ::Size, it changes ::Capacity

#
#include <iostream>
#include <fstream>
#include <istream>
#include <string>
#include <vector>

int main()
{
    std::vector<std::string> _resultColumnNames = { "hi", "my", "name", "is", "noah" };
    std::ofstream f("test", std::ios::binary);

    size_t num = _resultColumnNames.size();
    f.write(reinterpret_cast<const char*>(&num), sizeof(size_t));
    for (size_t i = 0; i < num; i++) {
        std::string resultColumnName = _resultColumnNames[i];
        size_t resultColumnNameLength = resultColumnName.length();
        f.write(reinterpret_cast<const char*>(&resultColumnNameLength), sizeof(size_t));
        f.write(resultColumnName.c_str(), resultColumnNameLength);
    }

    f.close();

    std::ifstream ifs("test", std::ios::binary);
    size_t numResultColumnNames;
    ifs.read(reinterpret_cast<char*>(&numResultColumnNames), sizeof(size_t));
    for (size_t i = 0; i < numResultColumnNames; i++) {
        size_t resultColumnNameLength;
        std::string resultColumnName;

        ifs.read(reinterpret_cast<char*>(&resultColumnNameLength), sizeof(size_t));
        resultColumnName.resize(resultColumnNameLength);

        ifs.read(reinterpret_cast<char*>(&resultColumnName[0]), resultColumnNameLength);

        std::cout << "[GEOMCACHE] resultColumnNameLength: " << resultColumnNameLength << "\n";
        std::cout << "[GEOMCACHE] resultColumnName: " << resultColumnName << "\n";
    }

    return 0;
}
#

this works

#

also, you seem to be using ifstream for writing? ifstream stands for input file stream, so you can only read.

#

ifstream doesnt even have the ::Write function for me

#

so asside from the syntax problems with the streams, if you fix the reserve to resize the string should be copied correctly