Create a class Employee with name, Id and salary as data members. Provide appropriate
constructors, set, get and display methods in the class.
In the main program, use a do-while loop to enter data for employees as long as the user
desires and save all data to a file.
Once the user is done with data entry, read the data for employees from the file and
display the information of each employee.

// Lab_13_A.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<iostream>
#include<conio.h>
#include<string>
#include<fstream>
using namespace std;

class emp
{
private:
    int id,sal;
    string name;
public:
    emp (int i=0,int sa=0,string s=""){id=i;sal=sa;name=s;}
    void set(int i=0,int sa=0,string s=""){id=i;sal=sa;name=s;}
    string getname(){return name;}
    int getid(){return id;}
    int getsal(){return sal;}
    void display()
    {
        cout<<"\nName: "<<name<<endl;
        cout<<"\nID: "<<id<<endl;
        cout<<"\nSalary: "<<sal<<endl;
    }
};


int _tmain(int argc, _TCHAR* argv[])
{
    int i,s;
    string n;
    char ch;
    ofstream inf("abc.txt");
    emp e;
    do
    {
        cout<<"Enter Name: ";
        cin>>n;
        cout<<"Enter ID: ";
        cin>>i;
        cout<<"Enter Salary: ";
        cin>>s;
        e.set(i,s,n);
        inf.write(reinterpret_cast<char *>(&e),sizeof(e));
        inf.close();
        cout<<"\nWant to add more: ";
        cin>>ch;
    }while(ch!='n');

    ifstream outf("abc.txt");
    while(!outf.eof())
    {
        outf.read(reinterpret_cast<char *>(&e),sizeof(e));
        e.display();
    }
    outf.close();

    getch();
}

The output is wrong.
When I Input more than one record, It shows just the first record in output.
Secondly It shows the same record 2 times, in the output.
Please Help people.
I have ( OOP/C++ ) semester exam in a week and I am very weak in file handling.

Attachments 2.png 36.92 KB 1.png 34.73 KB

Part of the problem is that you are closing the output file inside the loop you are reading and writing in, which means you are no longer actually writing to the file after the first pass. But that's just the start of the problem.

The problem is that you cannot write and read a whole object in like that to and from a file and expect it to be usable that way. An object (or even a POD struct, if it contains pointers or objects) has references to specific locations in memory (e.g., the virtual functions table), and reading in the data as a bulk record won't correctly recreate the object. Just as with the display() method you wrote, you need to read each individual instance variable in seperately. In the case of the string, since that is itself an object, you need to read the string data in as a char array first, or else use the input selector (>>) rather than the read() method. Since it involved private data, you would also need it to be in a method or a friend function.

Fortunately, there is a convention for this, which is independent of whether it is a file stream or not: you can overload the input and output selectors as friend functions of the class. We can even define how to display the data with custom manipulators, though that's a fairly advanced technique.

While we're at it, let's break the program up into separate components, rather than having it all in one big file.

emp.h

#include <iomanip>
#include <string>

const long CSV = 0x100;
const long CONSOLE = 0x200;


class emp
{
private:
    int id, sal;
    std::string name;

public:
    emp (int i=0,int sa=0, std::string s=""): id(i), sal(sa), name(s)
    {
        return;
    }

    std::string getname()
    {
        return name;
    }
    int getid()
    {
        return id;
    }
    int getsal()
    {
        return sal;
    }

    friend std::ostream& operator<<(std::ostream& os, emp& e);
    friend std::istream& operator>>(std::istream& is, emp& e);
};


std::ostream& operator<<(std::ostream& os, emp& e);
std::istream& operator>>(std::istream& is, emp& e);

std::ostream& console(std::ostream& os);
std::ostream& file(std::ostream& os);

std::istream& console(std::istream& is);
std::istream& file(std::istream& is);

#endif

emp.cpp

#include <iostream>
#include <string>
#include <sstream>
#include <map>
#include "emp.h"

std::map<std::string, long> UserFlag;

std::ostream& operator<<(std::ostream& os, emp& e)
{
    if (os.iword(UserFlag["EmpOutputFormat"]) == CSV)
    {
        // output the employee record as a comma-separated value
        os << e.name << ',' << e.id << ',' << e.sal << std::endl;
    }

    else if (os.iword(UserFlag["EmpOutputFormat"]) == CONSOLE)
    {
        os << "Name: " << e.name << std::endl;
        os << "ID: " << e.id << std::endl;
        os << "Salary: " << e.sal <<std::endl;
    }
    else
    {
        os << e.name << ' ' << e.id << ' ' << e.sal << std::endl;
    }

    return os;
}

std::istream& operator>>(std::istream& is, emp& e)
{
    if (is.iword(UserFlag["EmpInputFormat"]) == CSV)
    {
        std::string s;
        std::getline(is, s, ',');
        e.name = s;
        std::stringstream id;
        std::getline(is, s, ',');
        id << s;
        id >> e.id;
        std::stringstream sal;
        std::getline(is, s, '\n');
        sal << s;
        sal >> e.sal;
    }
    else if (is.iword(UserFlag["EmpInputFormat"]) == CONSOLE)
    {
        std::string s;

        std::cout << "Name: ";
        is >> e.name;
        is.ignore(1024, '\n');
        std::cout << "ID: ";
        is >> e.id;
        is.ignore(1024, '\n');
        std::cout << "Salary: ";
        is >> e.sal;
    }
    else
    {
        is >> e.name >> e.id >> e.sal;
    }

    return is;
}

std::ostream& console(std::ostream& os)
{
    if (UserFlag.find("EmpOutputFormat") == UserFlag.end())
    {
        UserFlag["EmpOutputFormat"] = os.xalloc();
    }

    os.iword(UserFlag["EmpOutputFormat"]) = CONSOLE;
    return(os);
}

std::ostream& file(std::ostream& os)
{
    if (UserFlag.find("EmpOutputFormat") == UserFlag.end())
    {
        UserFlag["EmpOutputFormat"] = os.xalloc();
    }

    os.iword(UserFlag["EmpOutputFormat"]) = CSV;
    return(os);
}

std::istream& console(std::istream& is)
{
    if (UserFlag.find("EmpInputFormat") == UserFlag.end())
    {
        UserFlag["EmpInputFormat"] = is.xalloc();
    }

    is.iword(UserFlag["EmpInputFormat"]) = CONSOLE;
    return(is);
}

std::istream& file(std::istream& is)
{
    if (UserFlag.find("EmpInputFormat") == UserFlag.end())
    {
        UserFlag["EmpInputFormat"] = is.xalloc();
    }

    is.iword(UserFlag["EmpInputFormat"]) = CSV;
    return(is);
}

main.cpp

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

using namespace std;

int main()
{
    int i,s;
    string n;
    char ch;
    ofstream outf("abc.txt");
    emp e;
    do
    {
        cin >> console >> e;
        outf << file << e;
        cout<< endl << "Want to add more? ";
        cin>>ch;
    }
    while(ch!='n');
    outf.close();

    ifstream inf("abc.txt");
    while(inf.good())
    {
        inf >> file >> e;
        cout << console << e;
    }
    inf.close();

    return 0;
}
This article has been dead for over six months. Start a new discussion instead.