How to save to file a struct containing strings

Good morning everyone

I'm trying to save a vector of this struct :

1
2
3
4
5
6
struct element
{
	std::string filename;
	std::string hash;
	bool isLocalized;
};


to a file, to read it later, in another program (so i cant just store addresses)
This works well when i change the type to char* instead of strings, but i'd like to know if there is a way to use strings :D (without libraries like boost or anything)

writing :

1
2
3
4
5
6
std::vector<element> v;
// Here loop to add elements to v
std::ofstream ofs("manifest.txt", std::ios::binary | std::ios::trunc);
if (!ofs.is_open()) return -1;
ofs.write(reinterpret_cast<char*>(v.data()), v.size()*sizeof(element));
ofs.close();


reading :

1
2
3
4
5
6
7
std::vector<element> w;
std::ifstream ifs("manifest.txt", std::ios::binary | std::ios::ate);
if (!ifs.is_open()) return -1;
auto file_len = ifs.tellg();
ifs.seekg(0, std::ios::beg);
w.resize(file_len / sizeof(element));
ifs.read(reinterpret_cast<char*>(&w[0]), file_len);


Thank you in advance ! :)
Last edited on
Something along these lines, perhaps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
struct manifest_element
{
    std::string filename;
    std::string hash;
    bool isLocalized;
};

// write contents of the structure to an output stream as plain text
// each object is written as three lines of text. format:
// line 1: filename
// line 2: hash
// line 3: isLocalised
// (assumes that filename and hash do not contain embedded new line characters,
//  if that is not the case, a different delimiter has to be used.)
std::ostream& operator<< ( std::ostream& stm, const manifest_element& elt )
{
    return stm << elt.filename << '\n' << elt.hash << '\n'
               << std::boolalpha << elt.isLocalized << '\n' ;
}

// read contents of the structure from an input stream
// input format is the same as what is written to the output stream
std::istream& operator>> ( std::istream& stm, manifest_element& elt )
{
    std::string filename;
    std::string hash;
    bool isLocalized;

    if( std::getline( stm, filename ) && std::getline( stm, hash ) && stm >> std::boolalpha >> isLocalized )
    {
        elt = { filename, hash, isLocalized } ; // set the fields
        stm.ignore( 1000, '\n' ) ; // extract and discard the newline after the last field
    }
    else elt = {} ; // input failed; clear all the fields

    return stm ;
}

And then:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
    // writing
    std::vector<manifest_element> vec;
    // fill vec

    std::ofstream ofs("manifest.txt"); // open in text mode
    if (!ofs.is_open()) return -1;

    for( const manifest_element& elt : vec ) ofs << elt ;
}

{
    // reading
    std::vector<manifest_element> vec;

    std::ifstream ifs("manifest.txt"); // open in text mode
    if (!ifs.is_open()) return -1;

    manifest_element elt ;
    while( ifs >> elt ) vec.push_back(elt) ;
}
Topic archived. No new replies allowed.