i made a program in dev c++ to merge contents of two files into a single file but the merged file is showing garbage outputs.

question:-
Write a C++ program to merge the content of two files namely “Employee.txt”
and
“Salary.txt” into “EmployeeDetails.txt”.

Sample contents of Employee.txt
EmployeeName EmployeeNumber Department Age
Rohit 12134 CSE 30
Ajay 13543 ECE 32
Bikash 12345 EEE 40

Sample contents of Employee.txt
GrossSalary NetSalary
12222 10000
22222 20000
32222 30000
Sample contents of the merged file EmployeeDetails.txt

EmployeeName EmployeeNumber Department Age GrossSalary Netsal
Rohit 12134 CSE 30 12222 10000
Ajay 13543 ECE 32 22222 20000
Bikash 12345 EEE 40 32222 30000

#include<iostream>
#include<conio.h>
#include<fstream>
using namespace std;
 
class emp
{
      int num,age;
      char name[20],dep[5];
       
      public:
          void getdata()
          {
             cout<<"\n\n  Name   = ";
             cin>>name;
             cout<<"\n Emp Num   = ";
             cin>>num;
             cout<<"\n Department= ";
             cin>>dep;
             cout<<"\n Age       = ";
             cin>>age;
          }
          void display1()
          { 
            cout<<"\n"<<name<<"\t"<<num<<"\t"<<dep<<"\t\t"<<age;
          } 
           
};
 
class sal
{
      float gs,ns;
       public:
           void getsal()
           {
             cout<<"\n Gross sal = ";
             cin>>gs;
             cout<<"\n Net sal   = ";
             cin>>ns;
           }
           void display2()
           {
             cout<<"\t"<<gs<<"\t"<<ns;
           }         
};
 
void display()
{
   emp e;sal s;
   fstream fil1;
    
   fil1.open("empdetails.txt",ios::in|ios::out);
 
   cout<<"\n\n Name \t Emp Num \t Dep \t Age \t Gross Sal \t Net Sal \n"; 
 
   do
   {
    fil1.read((char*)&e,sizeof(e));
    e.display1();
     
    fil1.read((char*)&s,sizeof(s));
    s.display2();
   }while(fil1);
    
}
              
int main()
{
    int n;
    emp e1;sal s1;
    fstream fil1,fil2,fil3;
     
    fil1.open("emp.txt",ios::in|ios::out);
    fil2.open("sal.txt",ios::in|ios::out);
    fil3.open("empdetails.txt",ios::in|ios::out);
    
    cout<<"\n How many employee details do you want to enter = ";
    cin>>n;
     
    cout<<"\n Enter the deatils one by one \n";
    for(int i=0;i<n;i++)
    {
        e1.getdata();
        fil1.write((char*)&e1,sizeof(e1));
         
        s1.getsal();
        fil2.write((char*)&s1,sizeof(s1));
         
        fil3.write((char*)&e1,sizeof(e1));//in these 2 steps i try to
        fil3.write((char*)&s1,sizeof(s1));//merge the contents of 
                                                   //   both objects
    }
    fil1.close();
    fil2.close();
    fil3.close();
     
    cout<<"\n\n\t\t Merged file contents \n\n\t\t";
    display();
    getch();
    return 0;
}

i am new to file programming.so please help me . i had my oops lab exam next week.thank u.

1) Make a class that has ALL of the employee details
EmployeeName, EmployeeNumber, Department, Age, GrossSalary, NetSalary

2) create (in the class) a method that returns a string that contains ALL of the employee details (delimited by {tab or comma})

3) Read the Employee.txt into an array, list, vector of EmployeeDetail objects
4) Read the Salary.txt and update each employee in the array with salary information

5) Create an output file and write the contents to the output using the string created by the built-in method in the class.

i have declared object for emp class--emp e1 inside main(). and i am getting i/p from user in getdata() and getsal() using e1.getdata() and s1.getsal()

Those operations are expecting user input. You should only read the contents of the file, right?

no no.at first i have to create both the files emp and sal (using user inputs) and then merge it in empdetails.txt.that's why there is getdata() in emp

Ah!
So in your display() or something like it, you will need to open two files.

Read a line from the first file
Read a line from the second file
concatenate the lines (space delimited)

write the concatenated line to the output display.
write the concatenated line to the output file.

but what is wrong with my code???

Don't know what to look for. We have no idea why you think the code is wrong. You didn't explain it to us.

Edited 5 Years Ago by WaltP: n/a

Why do you expect:

fil1.write((char*)&e1,sizeof(e1));

to write a human-readable line like your sample indicates? That's one (non-portable) way to write a terse binary record. Instead, for text files, keep it simple:

fil1 << e.name << " " << e.num << " " << e.dep << " " << e.age << endl;

and reverse that to read it back in:

fil1 >> e.name >> e.num >> e.dep >> e.age;

(Note, whitespace (including endl) tells the istream::operator>>() where to find boundaries of "items" and isn't read into any item. Use getline(fil1, lineString) to read an entire line (including whitespace) into a std::string variable.)

Also, if you need to create the files as well as merge them, then make those operations separate. Open a file for writing, fill it, and close it. Open another file for writing, fill it, and close it. Then open both files for reading, and a new file for writing, and perform the merge.

Ah!
So in your display() or something like it, you will need to open two files.

Read a line from the first file
Read a line from the second file
concatenate the lines (space delimited)

write the concatenated line to the output display.
write the concatenated line to the output file.

that's what i am doing in display() but why it is showing garbage values in o/p

Why do you expect:

fil1.write((char*)&e1,sizeof(e1));

to write a human-readable line like your sample indicates? That's one (non-portable) way to write a terse binary record. Instead, for text files, keep it simple:

fil1 << e.name << " " << e.num << " " << e.dep << " " << e.age << endl;

and reverse that to read it back in:

fil1 >> e.name >> e.num >> e.dep >> e.age;

(Note, whitespace (including endl) tells the istream::operator>>() where to find boundaries of "items" and isn't read into any item. Use getline(fil1, lineString) to read an entire line (including whitespace) into a std::string variable.)

Also, if you need to create the files as well as merge them, then make those operations separate. Open a file for writing, fill it, and close it. Open another file for writing, fill it, and close it. Then open both files for reading, and a new file for writing, and perform the merge.

that's what i am asking why is
fil1.write((char*)&e1,sizeof(e1)) & fil1.read((char*)&e1,sizeof(e1)) not working.i want to use class and my sir told me that in this program u have to write it via object.

seondly as far as merging is concerned what is wrong in my code . i am trying to write contents in both the file and after that merging them in employeedetails.txt as soon as an i/p is over for an employee.what is wrong with this logic??

Edited 5 Years Ago by shikhar02: n/a

I can't tell you why fil1.write() and fil1.read() aren't working, without more information. What values are you entering for e1? What file gets generated when you write() it? What is in e1 after you read() it back?

I don't know what your professor meant by "write it via object." To me that means something more like:

class emp
{
...
    void write(ofstream & fil) const {
        fil << name << " " << num << " " << dep << " " age << endl;
    }
    void read(ifstream & fil) {
        fil >> name >> num >> dep >> age;
    }
...
};

so that later you can do:

e1.write(fil1);
    e2.read(fil2);

There's nothing wrong with your logic, if it addresses your assignment. However, what you specified is

question:-
Write a C++ program to merge the content of two files namely “Employee.txt”
and “Salary.txt” into “EmployeeDetails.txt”.

and what you've programmed does not do that, it generates all three files at the same time. I'm just trying to help.

As far as writing out binary files (using read() and write() the way you are so far), I think you need to open the files in "binary" mode. Include flag ios::binary when you open the file. And if the only operation you're performing on a file is writing (or reading), then don't specify the other flag, just ios::out (or ios::in), not both.

I can't tell you why fil1.write() and fil1.read() aren't working, without more information. What values are you entering for e1? What file gets generated when you write() it? What is in e1 after you read() it back?

I don't know what your professor meant by "write it via object." To me that means something more like:

class emp
{
...
    void write(ofstream & fil) const {
        fil << name << " " << num << " " << dep << " " age << endl;
    }
    void read(ifstream & fil) {
        fil >> name >> num >> dep >> age;
    }
...
};

so that later you can do:

e1.write(fil1);
    e2.read(fil2);

There's nothing wrong with your logic, if it addresses your assignment. However, what you specified is

and what you've programmed does not do that, it generates all three files at the same time. I'm just trying to help.

As far as writing out binary files (using read() and write() the way you are so far), I think you need to open the files in "binary" mode. Include flag ios::binary when you open the file. And if the only operation you're performing on a file is writing (or reading), then don't specify the other flag, just ios::out (or ios::in), not both.

i made some changes like in main i made all the file objects ofstream type and in display ifstream and ios::binary as you said . now it works but one problem the last employee details is printed twice on the screen. why is this so??

Probably because of when you check for errors on your input stream:

do
{
    fil1.read((char*)&e,sizeof(e));
    e.display1();
 
    fil1.read((char*)&s,sizeof(s));
    s.display2();
} while (fil1);

After you've read the last e and s out of the file, the fil1 stream is still in a valid state, so you repeat your loop one more time. Each read fails, but since there's no data to replace the variable, it maintains the same values it had from the previous read, so prints the same line as previously.

One solution is to test the state of fil1 after reading e (but before printing it), and if it's at EOF or otherwise in an error-state, break; out of the loop at that point.

Probably because of when you check for errors on your input stream:

do
{
    fil1.read((char*)&e,sizeof(e));
    e.display1();
 
    fil1.read((char*)&s,sizeof(s));
    s.display2();
} while (fil1);

After you've read the last e and s out of the file, the fil1 stream is still in a valid state, so you repeat your loop one more time. Each read fails, but since there's no data to replace the variable, it maintains the same values it had from the previous read, so prints the same line as previously.

One solution is to test the state of fil1 after reading e (but before printing it), and if it's at EOF or otherwise in an error-state, break; out of the loop at that point.

thank's man i did what you told and now it works.thanks a lot

This question has already been answered. Start a new discussion instead.