1

I have created a class Scholar with attributes: string name, int id, char grade. Then, I had written the data in text file in binary mode using program P1. I had another program P2 which inserts a new data in between previous data.

It shows data (using program P1) when I initially created the text file with some objects. But, when I inserted a new data (using program P2), the attributes id and grade appears but, the attribute name went missing.

The Scholar class code:

#ifndef SCHOLAR_H
#define SCHOLAR_H
#include <iostream>
#include <cstdio>
using namespace std;

class Scholar {
    int id;
    string name;
    char grade;

public:
    void read_data() {
        cout << "\nEnter ID: ";
        cin >> id;
        string temp;
        getline(cin, temp);
        cout << "Enter name: ";
        getline(cin, name);
        cout << "Enter grade: ";
        cin >> grade;
    }

    void print_data() {
        cout << "\nID: " << id << " | Name: " << name << " | Grade: " << grade;
    }

    int modify_data();
    int _id() {
        return id;
    }

    string _name() {
        return name;
    }

    char _grade() {
        return grade;
    }
};

#endif // SCHOLAR_H

Program P1:

#include "MyHeaderFiles/Scholar.h"
#include <fstream>
#include <cstdlib>
#include <cctype>

int main() {
    system("cls");

    Scholar sch;
    fstream fs;
    fs.open("SchDB.txt", ios::out | ios::in | ios::binary | ios::trunc);

    if(!fs) {
        cerr << "File not found!";
        system("PAUSE");
    }

    char reply;
    do {
        sch.read_data();
        fs.write((char*) &sch, sizeof(sch));

        cout << "Do you want to add another scholar (y/n) : ";
        cin >> reply;
    } while(tolower(reply) == 'y');

    fs.seekg(0);
    cout << "\nFile content\n------------" << endl;
    while(!fs.eof()) {
        fs.read((char*) &sch, sizeof(sch));
        if(fs.eof()) break;

        sch.print_data();
    }

    fs.close();
    cout << endl;
    return 0;
}

The initial image of output when I hadn't inserted any new data:

Initial Image You can see the names!

Program P2:

#include "MyHeaderFiles/Scholar.h"
#include <fstream>
#include <cstdlib>

int main() {
    system("cls");
    Scholar sch;
    Scholar newSch;
    ofstream fout;
    ifstream fin;
    fout.open("Temp.txt", ios::out | ios::binary);
    fin.open("SchDB.txt", ios::in | ios::binary);

    char last = 'y';
    int pos;
    cout << "\nYou have to enter data of a new student." << endl;
    newSch.read_data();

    fin.seekg(0);
    cout << "\nFile content\n------------" << endl;
    while(!fin.eof()) {
        pos = fin.tellg();
        fin.read((char*) &sch, sizeof(sch));
        if(sch._id() > newSch._id()) {
            fout.write((char*) &newSch, sizeof(newSch));
            last = 'n';
            break;
        } else {
            fout.write((char*) &sch, sizeof(sch));
        }
    }

    if(last == 'y') {
        fout.write((char*) &newSch, sizeof(newSch));
    } else if(!fin.eof()) {
        fin.seekg(pos);
        while(!fin.eof()) {
            fin.read((char*) &sch, sizeof(sch));
            if(fin.eof()) break;
            fout.write((char*) &sch, sizeof(sch));
        }
    }

    fin.close();
    fout.close();

    remove("SchDB.txt");
    rename("Temp.txt", "SchDB.txt");
    fin.open("SchDB.txt", ios::in | ios::binary);

    fin.seekg(0);
    while(!fin.eof()) {
        fin.read((char*) &sch, sizeof(sch));
        if(fin.eof()) break;
        sch.print_data();
    }

    fin.close();
    cout << endl;
    return 0;
}

The later image when I used the program P2 to insert new data:

Later Image And, now you can see only the name attribute is missing!

I am using Code::Blocks IDE and GNU GCC Compiler.

Can anybody explain me why the string isn't showing up?

  • check return of `remove` and `rename` – Joseph D. May 08 '18 at 04:33
  • @codekaizer, both returned 0. –  May 08 '18 at 04:36
  • 2
    The characters in a string are allocated elsewhere on the heap. Saving the string does not save its contents. Use a char array to do that. – stark May 08 '18 at 04:38
  • You can't read and write `string`s, or objects that contain them, like that. Read about serialization. (There must be dupes of this, but I can't find a good one.) – molbdnilo May 08 '18 at 04:39
  • Thanks @stark, that worked. But, I need string datatype, as size of char array needs to be determined before run-time. –  May 08 '18 at 04:44
  • You need to read [Why is `iostream::eof` inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – molbdnilo May 08 '18 at 04:44
  • @molbdnilo, Ya, you're right. And that's why, I used `if(fin.eof()) break;` just after `fin.read((char*) &sch, sizeof(sch));` inside the `while` loop. –  May 08 '18 at 04:49

0 Answers0