hello all
i want to know the proplem with this program

and first ........ can i write a string object to a file normally like other objects ??

this is the code ......the program writes the file but it can't read it again

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

enum ClassType
{
    STUDENT, PROF
};

class person
{
protected:
    int id;
    string name;
    static vector<person*> arr;
public:

    person() : id(0), name("")
    {
    }

    virtual void GetData()
    {
        cout << "ID:";
        cin >> id;
        cout << "Name:";
        cin >> name;
    }

    virtual void ShowData()
    {
        cout << "ID:" << id << "\nName:" << name;
    }

    virtual ClassType GetType();
    static void Add();
    static void ShowAll();
    static void Save();
    static void Load();
};
vector<person*> person::arr;

class prof : public person
{
protected:
    int students;
    int years;

public:

    prof()
    {
        person();
        students = 0;
        years = 0;
    }

    void GetData()
    {
        person::GetData();
        cout << "Students No.:";
        cin >> students;
        cout << "Years No.:";
        cin >> years;
    }

    void ShowData()
    {
        person::ShowData();
        cout << "\nStudents No.:" << students << "\nYears No.:" << years << endl;
    }

};

class student : public person
{
protected:
    int AVGGrade;
    int year;
public:

    student()
    {
        person();
        AVGGrade = 1;
        year = 1;
    }

    void GetData()
    {
        person::GetData();
        cout << "Student Grade.:";
        cin >> AVGGrade;
        cout << "Year No.:";
        cin >> year;
    }

    void ShowData()
    {
        person::ShowData();
        cout << "\nStudent AVGG.:" << AVGGrade << "\nYear No.:" << year << endl;
    }
};

ClassType person::GetType()
{
    if (typeid (*this) == typeid (prof))
        return PROF;
    else if (typeid (*this) == typeid (student))
        return STUDENT;
}

void person::Add()
{
    char c;
    cout << "p for prof and s for student:";
    cin >> c;
    person *ptr;
    switch (c)
    {
    case 'p':
        ptr = new prof;
        arr.push_back(ptr);
        break;
    case 's':
        ptr = new student;
        arr.push_back(ptr);
    }
    (arr.back())->GetData();
}

void person::ShowAll()
{
    for (int i = 0; i < arr.size(); i++)
        arr[i]->ShowData();
}

void person::Save()
{
    ofstream file("DATA.bin", ios::binary | ios::trunc);
    ClassType CurrentObj;
    int size;
    for (int i = 0; i < arr.size(); i++)
    {
        CurrentObj = arr[i]->GetType();
        //cout << "\nH1\n";
        file.write(reinterpret_cast<char*> (&CurrentObj), sizeof (ClassType));
        //cout << "\nH2\n";
        switch (CurrentObj)
        {
        case PROF:
            size = sizeof (prof);
            break;
        case STUDENT:
            size = sizeof (student);
        }
        file.write(reinterpret_cast<char*> (arr[i]), size);
        switch (CurrentObj)
        {
        case PROF:
            cout << "\nI Wrote " << size << " Of Type Prof";
            break;
        case STUDENT:
            cout << "\nI Wrote " << size << " Of Type Student";
        }

    }
}

void person::Load()
{
    ifstream file("DATA.bin", ios::binary);
    ClassType CurrentObj;
    person *TempObj;
    while (file)
    {
        file.read(reinterpret_cast<char*> (&CurrentObj), sizeof (ClassType));
        if (CurrentObj == PROF)
        {
            TempObj = new prof;
            cout << "\nReading Prof";
            file.read(reinterpret_cast<char*> (TempObj), sizeof (prof));
            cout << "\nProf Was Read";
        }
        else if (CurrentObj == STUDENT)
        {
            TempObj = new student;
            cout << "\nReading Student";
            file.read(reinterpret_cast<char*> (TempObj), sizeof (student));
            cout << "\nStudent Was Read\n\n";
        }
            
        TempObj->ShowData();
    }
    system("pause");
}

int main(int argc, char* argv[])
{
    char c;
    cin >> c;
    switch (c)
    {
    case 'a':
        person::Add();
        person::Add();
        person::Save();
        break;
    case 'l':
        person::Load();
    }
    //person::Add();
    //person::Add();
    //person::Add();
    //person::Save();
    //perosn::Load();
    //person::ShowAll();
    return 0;
}

Recommended Answers

All 2 Replies

Using read and write to serialize your objects is generally a bad idea. At the risk of being too vague, I'll distill all of my experience into one piece of advice for your convenience:

When you want to serialize an object manually, convert each of the fields to a string, format them as desired, and then write the string to a file. When you want to deserialize an object manually, read the string from your file, parse the string in a constructor, and populate the data members.

In code form, such a solution would look like this:

#include <sstream>
#include <string>
#include <vector>

class student {
public:
  std::string name;
  std::vector<std::string> classes;
  std::vector<int> grades;
public:
  student() {}
  student ( const std::string& serialized )
  {
    std::stringstream src ( serialized );
    std::string class_name;
    int grade;

    // No error checking
    std::getline ( src, name, '|' );

    while ( std::getline ( src, class_name, '|' ) ) {
      classes.push_back( class_name );
      src>> grade;
      grades.push_back ( grade );
    }
  }
public:
  std::string serialize ( std::ostream& out )
  {
    // Assume grades and classes are parallel
    // No error checking
    std::stringstream serialized;

    serialized<< name <<'|';

    std::vector<std::string>::size_type i;

    for ( i = 0; i < classes.size(); i++ ) {
      if ( i != 0 )
        serialized<<'|';

      serialized<< classes[i] <<'|'<< grades[i];
    }

    out<< serialized.str();

    return serialized.str();
  }
};

This way you don't have to know the POD type rules, you don't have to worry about what's undefined behavior and what isn't, and you retain maximum portability.

thanks Very much

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.