Aman
Aman

Reputation: 15

error in storing a map of strig in class object in a binary file

i have a string object in map object which is in a class object then it is giving me error what to do

#include <iostream>
#include <fstream>
#include <map>
#include<cstring>
using namespace std;

class student
{
public:
    int rollno;
    char name[50];
    int sub[10];
    map<string, int> marks;
};
int main()
{

    int totalsub;
    student st;
    st.rollno=21;
    strcpy(st.name,"Aman Tiwari");
    cout << "enter total subject :";
    cin >> totalsub;
    for (int i = 0; i < totalsub; i++)
    {
        int num;
        string str;
        cin.ignore();
        cout << "enter " << i << " subject name :";
        getline(cin,str);
        cout << "enter marks:";
        cin >> num;
**        st.marks.insert(pair<string, int>(str, num));**
    }
    // cout << "total data is :" << endl;
    // for (auto &mark : st.marks)
    // {
    //     cout << mark.first << " " << mark.second << endl;
    // }

    ofstream ofobj;
    ofobj.open("test.dat",ios::binary|ios::app);

    ofobj.write(reinterpret_cast<char*>(&st),sizeof(student));
    ofobj.close();

    ifstream ifobj;
    ifobj.open("test.dat", ios::binary | ios::in);
    student temp;
    ifobj.read(reinterpret_cast<char *>(&temp), sizeof(student));

    cout << " the data is " << endl;
    cout << temp.rollno<<endl;
    cout << temp.name<<endl;
    for (auto &mark : temp.marks)
    {
        cout << mark.first << " " << mark.second << endl;
    }

    cout<<"After showing !!";
    return 0;
}

this problem is occured due to string object in class object and map object doesn't stores character array otherwise i will be able to store student object in file containing map of string and int.

Upvotes: -1

Views: 39

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 597906

You can't write/read a student object as-is directly to/from the file, because its marks member is a non-trivial std::map type. You will have to instead serialize/deserialize the student's data, eg:

template<typename T>
void writeToStream(std::ostream &os, const T &value) {
    os.write(reinterpret_cast<const char*>(&value), sizeof(value));
}

template<typename T>
void readFromStream(std::istream &is, T &value) {
    is.read(reinterpret_cast<char*>(&value), sizeof(value));
}

void writeToStream(std::ostream &os, const std::string &value) {
    size_t size = value.size();
    writeToStream(os, size);
    os.write(value.c_str(), size);
}

void readFromStream(std::istream &is, std::string &value) {
    size_t size;
    readFromStream(is, size);
    value.resize(size);
    is.read(value.data(), size);
}

class student
{
public:
    int rollno;
    char name[50];
    int sub[10];
    std::map<string, int> marks;
    
    void writeTo(std::ostream &os) const {
        writeToStream(os, rollno);
        writeToStream(os, name);
        writeToStream(os, sub);
        writeToStream(os, marks.size());
        for(const auto &mark : marks) {
            writeToStream(os, mark.first);
            writeToStream(os, mark.second);
        }
    }

    void readFrom(std::istream &is) {
        readFromStream(is, rollno);
        readFromStream(is, name);
        readFromStream(is, sub);
        size_t size;
        readFromStream(is, size);
        marks.clear();
        for(size_t i = 0; i < size; ++i) {
            std::string first;
            int second;
            readFromStream(is, first);
            readFromStream(is, second);
            marks.emplace(first, second);
        }
    }
};

int main()
{
    ...

    std::ofstream ofobj("test.dat", ios::binary|ios::app);
    st.writeTo(ofobj);
    ofobj.close();

    std::ifstream ifobj("test.dat", ios::binary | ios::in);
    student temp;
    temp.readFrom(ifobj);
    ifobj.close();

    ...
}

Upvotes: 0

Related Questions