0

I tried the below code to write an object to a dat file:

#include<iostream>
#include<fstream>
#include<string>
#include<string.h>

using namespace std;
class Student
{ //data members
    int adm;
    string name;
public:
    Student()
    {
        adm = 0;
        name = "";
    }
    Student(int a,string n)
    {
        adm = a;
        name = n;
    }
    Student setData(Student st) //member function
    {
        cout << "\nEnter admission no. ";
        cin >> adm;
        cout << "Enter name of student ";
        cin.ignore();
        getline(cin,name);
        st = Student(adm,name);
        return st;
    }

    void showData()
    {
        cout << "\nAdmission no. : " << adm;
        cout << "\nStudent Name : " << name;
    }

    int retAdmno()
    {
        return adm;
    }
};

/*
* function to write in a binary file.
*/
void demo()
{
    ofstream f;
    f.open("student.dat",ios::binary);

    for(int i = 0;i<4;i++)
    {
        Student st;
        st = st.setData(st);
        f.write((char*)&st,sizeof(st));
    }
    f.close();
    ifstream fin;
    fin.open("student.dat",ios::binary);
    Student st;
    while(!fin.eof())
    {
        fin.read((char*)&st,sizeof(st));
        st.showData();
    }
}
int main()
{
    demo();
    return 0;
}

But when I am executing the demo function I am getting some garbage values from the "student.dat" file. I am creating a database and want to get the records but I am not able to get all the records in the dat file.

Please suggest a solution

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • `Student Student::setData(Student st)` is a really weird member function. It's a member function, so you need to call it on an existing `Student` object. You need to pass a second `Student` object as an argument `st`, just for it to be ignored and overwritten. And finally you return a third Student object. – MSalters Oct 28 '21 at 07:39
  • This is a FAQ. You cannot use fread/fwrite or `fstream::{read,write}` to dump `std::string`s to disk. Invent a proper serialization format or use an existing one. [Using fread/fwrite for STL string. Is it correct?](https://stackoverflow.com/questions/6782632/using-fread-fwrite-for-stl-string-is-it-correct) – Botje Oct 28 '21 at 07:42
  • You can't store non-trivial objects, like `std::string`, like that. Read about serialization, or define a more suitable type. – molbdnilo Oct 28 '21 at 07:42
  • Suggestion: Try giving JSON or some sort of Database or some other text format if storing student data is your actual goal. – demberto Nov 04 '21 at 11:58

1 Answers1

0

You cannot write complex data types to a file in binary mode. They have some additional variables and functions inside,which you do not know or see. Those data types have some internal state that or context dependent. So, you cannot store in binary and then reuse it somewhere else. That will never work.

The solution is serialization/deserialization.

This sounds complicated, but is not at all in your case. It basically means that all your data from your struct shall be converted to plain text and put in a text-file.

For readin the data back, it will be first read as text, and then converted to your internal data structures.

And the default approach for that is to overwrite the inserter << operator and extractor >> operator.

See the simple example in your modified code:

#include<iostream>
#include<fstream>
#include<string>
#include<iomanip>


class Student
{ //data members
    int adm;
    std::string name;
public:
    Student()
    {
        adm = 0;
        name = "";
    }
    Student(int a, std::string n)
    {
        adm = a;
        name = n;
    }
    Student setData(Student st) //member function
    {
        std::cout << "\nEnter admission no. ";
        std::cin >> adm;
        std::cout << "Enter name of student ";
        
        std::getline(std::cin>> std::ws, name);
        st = Student(adm, name);
        return st;
    }
    void showData()
    {
        std::cout << "\nAdmission no. : " << adm;
        std::cout << "\nStudent Name : " << name;
    }
    int retAdmno()
    {
        return adm;
    }
    friend std::ostream& operator << (std::ostream& os, const Student& s) {
        return os << s.adm << '\n' << s.name << '\n';
    }
    friend std::istream& operator >> (std::istream& is, Student& s) {
        return std::getline(is >> s.adm >> std::ws, s.name);
    }
};

/*
* function to write in a binary file.
*/
void demo()
{
    std::ofstream f("student.dat");
    for (int i = 0; i < 4; i++)
    {
        Student st;
        st = st.setData(st);
        f << st;
    }
    f.close();
    std::ifstream fin("student.dat");
    Student st;
    while (!fin.eof())
    {
        fin >> st;
        st.showData();
    }
}
int main()
{
    demo();
    return 0;
}
A M
  • 14,694
  • 5
  • 19
  • 44