Write Array of a Class to a file -- Overloading << Overloading

closed account (iAqMGNh0)
Hey folks.
I am 96% finished with a final project for my first c++ course and I've run into trouble with writing out the array of my class to a file. I have read IN information to the class array from a .txt file just fine. But when applying the same logic to printing the same array out to a file I receive the following error message.

error: no match for 'operator<<' (operand types are 'std::ofstream {aka std::basic_ofstream<char>}' and 'void')

I've been looking into possible solutions. I know I should probably be overloading the << operator but I don't know exactly how to to that. I've looked at so many examples online but I can't seem to apply what I've been reading to my own code. Most people have told me to use vectors. I... do not know what a vector is. We haven't gotten that far in the course.

I've trimmed as much of the code as I can to the bare minimum but if any more code is needed I'll gladly share -- I just don't want to put too much of this assignment out there. It's a program the uses a switch-case menu to read in information and calculate a payroll (among other things).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Employee
{
private:
    int empID;
    string empName;
    int day1, day2, day3, day4, day5;
    float empWage;
    float deduction;
public:
    void setData(int,string,int,int,int,int,int,float,float);
    void getData(void);
    void printMenu();
    void printEmpData();
    void printPayroll();
};


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void Employee::setData(int id,string name,int d1,int d2,int d3,int d4,int d5,float wage,float ded)
{
    empID = id;
    empName = name;
    day1 = d1;
    day2 = d2;
    day3 = d3;
    day4 = d4;
    day5 = d5;
    empWage = wage;
    deduction = ded;
}

void Employee::printPayroll()
{
    int totalHour = day1+day2+day3+day4+day5;
    float totalWage = totalHour * empWage;
    float finalWage = totalWage - deduction;
     
        cout<<"  "<<empID<<"\t\t"<<empName<<"\t\t";
        cout<<totalHour<<"\t\t";
        cout<<"$"<<totalWage<<"\t\t";
        cout<<"$"<<deduction<<"\t\t";
        cout<<"$"<<finalWage<<endl;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
int main()
{
    ifstream in;
    ofstream outPut;
    int newI = 0;
    Employee emp[20];

        //case '1':
        {
            in.open("test.txt");
            int i=0;
            int id, d1, d2, d3, d4, d5;
            float wage, ded;
            string name;

            if(in.is_open())
            {
                while((!in.eof()))
                {
                    in>>id>>name>>d1>>d2>>d3>>d4>>d5>>wage>>ded;
                    emp[i].setData(id,name,d1,d2,d3,d4,d5,wage,ded);
                    emp[i].getData();
                    i++;
                    newI = i;
                }
                cout<<endl;
                in.close();
            }
            else
            {
                cout<<"\n  Unable to open file."<<endl<<endl;
            }
        }
        //break;

        //case '7':
        {
            outPut.open("outputFile.txt");
            {
                if(outPut.is_open())
                {
                   for(int j=0; j<newI; j++)
                    {
                        outPut<<emp[j].printPayroll();
                    }
                }
                else
                cout<<"Nope!";
                outPut.close();
            }
        }
        //break;
return 0;
}


Should I be using something like this in my class?
 
friend ostream& operator<<(ostream& outPut, const Employee& emp);


ETA: I'm an idiot. I'm sorry. This is the file being read in:
1
2
3
4
5
6
7
8
9
10
100 Joseph 1 8 3 4 5 13 300.10 
101 John 5 6 7 8 9 12 35.10 
102 Jo 5 4 3 2 1 11 20.10 
103 Johan 8 9 8 7 6 10 25.10 
104 Jacob 7 8 5 6 2 10 20.5
105 Josiah 7 2 6 1 4 13.5 30.10 
106 Jenny 8 6 3 3 5 12.5 32.10 
107 Job 2 2 2 2 2 11.5 10.10 
108 Jane 0 0 0 0 1 10.3 5 
109 Jared 8 8 8 8 8 10.25 20.5
Last edited on
Should I be using something like this in my class?
This is one possible way. It may replace printPayroll().

Another way would be providing ostream to printPayroll():
1
2
3
4
5
6
7
8
9
10
11
12
void Employee::printPayroll(ostream& outPut) const // Note const to use it with a const object
{
    int totalHour = day1+day2+day3+day4+day5;
    float totalWage = totalHour * empWage;
    float finalWage = totalWage - deduction;
     
        outPut<<"  "<<empID<<"\t\t"<<empName<<"\t\t"; // Note: outPut instead of cout
        outPut<<totalHour<<"\t\t";
        outPut<<"$"<<totalWage<<"\t\t";
        outPut<<"$"<<deduction<<"\t\t";
        outPut<<"$"<<finalWage<<endl;
}
You may combine both approaches like so:
1
2
3
4
5
friend ostream& operator<<(ostream& outPut, const Employee& emp)
{
  emp.printPayroll(outPut);
  return outPut;
}
closed account (iAqMGNh0)
Thank you so much for your input code777! I took your suggestion and provided ostream to a copy of printPayroll() that I have named outputPayroll() (I have to keep a regular copy of printPayroll() for another section of my program). My updated code looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
void Employee::outputPayroll(ostream& outPut) const object
{
    int totalHour = day1+day2+day3+day4+day5;
    float totalWage = totalHour * empWage;
    float finalWage = totalWage - deduction;

        outPut<<"  "<<empID<<"\t\t"<<empName<<"\t\t";
        outPut<<totalHour<<"\t\t";
        outPut<<"$"<<totalWage<<"\t\t";
        outPut<<"$"<<deduction<<"\t\t";
        outPut<<"$"<<finalWage<<endl;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        case '7':
        {
            outPut.open("outputFile.txt");
            {
                if(outPut.is_open())
                {
                    outPut<<"  ID No.\tEmployee Name\tTotal Hours\tSalary\t\tDeduction\tFinal Salary"<<endl;

                    for(int j=0; j<newI; j++)
                    {
                        outPut<<emp[j].outputPayroll(ostream& outPut) const;
                    }
                }
                else
                    cout<<"NOpe!";
                outPut.close();
            }
        }

        break;


I'm sure I'm still not doing the implementation right in the main program and when I compile I get the error report "error: expected primary-expression before '&' token".

However! This is much better than the error report I had before! I will keep looking at my code and see if I can parse this out on my own. I really appreciate your help!
Line 11: outPut<<emp[j].outputPayroll(ostream& outPut) const;

and

void Employee::outputPayroll(ostream& outPut) const object
Last edited on
Another approach:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Employee
{
private:
    int empID;
    string empName;
    int day1, day2, day3, day4, day5;
    float empWage;
    float deduction;
public:
    void setData(int,string,int,int,int,int,int,float,float);
    void getData(void);
    void printMenu();
    void printEmpData();
    void printPayroll( ostream& out = cout ) const;
};

void Employee::printPayroll( std::ostream& out ) const
{
  // printing something to out
}

// The operator does not have to be a friend:
ostream& operator<< ( ostream& outPut, const Employee& emp )
{
  emp.printPayroll( outPut );
  return outPut;
}

Allows:
1
2
3
4
5
6
ofstream ofile( "data.txt" );
Employee bob;
ofile << bob;
bob.printPayroll( ofile );
cout << bob;
bob.printPayroll(); // same as bob.printPayroll( cout ); 

closed account (iAqMGNh0)
Thank you SO SO SO much coder777 and keskiverto! My program now runs perfectly and prints everything to the file.

Here's the updated code for those interested in the changes I made.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Employee
{
private:
    int empID;
    string empName;
    int day1, day2, day3, day4, day5;
    float empWage;
    float deduction;
public:
    void setData(int,string,int,int,int,int,int,float,float);
    void getData(void);
    void printMenu();
    void printEmpData();
    void outputPayroll( ostream& out = cout ) const;
};

void Employee::outputPayroll( std::ostream& outPut ) const
{
    int totalHour = day1+day2+day3+day4+day5;
    float totalWage = totalHour * empWage;
    float finalWage = totalWage - deduction;

        outPut<<"  "<<empID<<"\t\t"<<empName<<"\t\t"; // Note: outPut instead of cout
        outPut<<totalHour<<"\t\t";
        outPut<<"$"<<totalWage<<"\t\t";
        outPut<<"$"<<deduction<<"\t\t";
        outPut<<"$"<<finalWage<<endl;
}

ostream& operator<< (ostream& outPut, const Employee& emp)
{
  emp.outputPayroll(outPut);
  return outPut;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        //case '7':
        {
            ofstream outPut;
            outPut.open("outputFile.txt");
            {
                if(outPut.is_open())
                {
                    outPut<<"  ID No.\tEmployee Name\tTotal Hours\tSalary\t\tDeduction\tFinal Salary"<<endl;
                    for(int j=0; j<newI; j++)
                    {
                        emp[j].outputPayroll(outPut);
                    }
                }
                else
                    cout<<"NOpe!";
                outPut.close();
            }
        }

        //break; 
You could replace the emp[j].outputPayroll(outPut);
with outPut << emp[j];
Topic archived. No new replies allowed.