Read Failed

Here is my code thus far, I am attempting to create a simple payroll program. It is supposed to display the two employees that I have created, one for a moment and then another. I have been at this a while and need some input to fixing my solution. I am currently getting a Read Failed error on line 39 of my driver. I cannot correct this to not get caught on this error. Any help would be appreciated.

employee.h
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <fstream>
#include <string>

using namespace std;

//Provides start point for employee information
class Employee
{
private:
	//Setting initial values
	int employeeNumber;
	string employeeName;
	string employeeAddress;
	string phoneNumber;
	double hourlyWage;
	double weeklyHours;
	double calcPay;

public:
	//Default constructor
	//Purpose: Initialize data in employee object to null
	//Parameters: None
	//Returns: None
	Employee( );

	//Parameterized constructor
	//Purpose: Initialize data in employee object to specified data
	//Parameters: Employee number, name, address, phone number, hourly wage, week hours
	//Returns: None
	Employee(int, string, string, string, double, double);

	//readEmployee function
	//Purpose: Reads employee information from a file
	//Parameters: A reference from the ifstream object
	//Returns: True if read is successful
	bool readEmployee(ifstream&);

	//writeEmployee function
	//Purpose: Writes employee information to a file
	//Parameters: A reference from the ofstream object
	//Returns: None
	void writeEmployee(ofstream&);

	// getEmployeeNumber function
	// Purpose: returns number of employee
	// Parameters: none
	// Returns: The employees number
	int getEmployeeNumber( ) const;

	// getName function
	// Purpose: Returns name of employee
	// Parameters: none
	// Returns: The employees name
	string getEmployeeName( ) const;

	// getAddress function
	// Purpose: Returns address of employee
	// Parameters: none
	// Returns: The employees address
	string getEmployeeAddress( ) const;

	// getPhoneNumber function
	// Purpose: Returns phone number of employee
	// Parameters: none
	// Returns: The employees phone number
	string getPhoneNumber( ) const;

	// getHourlyWage function
	// Purpose: Returns hourly wage of employee
	// Parameters: none
	// Returns: The employees wage
	double getHourlyWage( ) const;

	// getWeeklyHours function
	// Purpose: Returns weekly hours of employee
	// Parameters: none
	// Returns: The employees weekly hours
	double getWeeklyHours( ) const;

	// getCalcPay function
	// Purpose: Returns total pay for the employee
	// Parameters: none
	// Returns: The employees paycheck
	double getCalcPay( ) const;
};

employee.cpp
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "employee.h"

//Declaring constants
int WEEK_MAX = 40;
double FED_TAX = 0.20;
double STATE_TAX = 0.075;
double OVER_TIME = 1.5;

//Declaring variables 
double netPay;
double fedTotal;
double stateTotal;
double payCheck;
double overHours;
double overPay;
double regularPay;

Employee::Employee()
{
	employeeNumber = 0;
	employeeName = "";
	employeeAddress = "";
	phoneNumber = "";
	hourlyWage = 0.00;
	weeklyHours = 0.00;
}

Employee::Employee(int eNumber, string eName, string eAddress, string pNumber, double hWage, double wHours)
{
	employeeNumber = eNumber;
	employeeName = eName;
	employeeAddress = eAddress;
	phoneNumber = pNumber;
	hourlyWage = hWage;
	weeklyHours = wHours;
}

bool Employee::readEmployee(ifstream& input)
{
	if (input >> employeeNumber && input >> employeeName && input >> employeeAddress && input >> phoneNumber && input >> hourlyWage && input >> weeklyHours)
	{
		return true;
	}
	else
	{
		return false;
	}
}

void Employee::writeEmployee(ofstream& output)
{
	//No error checking when writing a file
	output << employeeNumber << ' ' << employeeName << ' ' << employeeAddress << ' ' << phoneNumber << ' ' << hourlyWage << ' ' << weeklyHours;
}

int Employee::getEmployeeNumber( ) const
{
	return employeeNumber;
}

string Employee::getEmployeeName( ) const
{
	return employeeName;
}

string Employee::getEmployeeAddress( ) const
{
	return employeeAddress;
}

string Employee::getPhoneNumber( ) const
{
	return phoneNumber;
}

double Employee::getHourlyWage( ) const
{
	return hourlyWage;
}

double Employee::getWeeklyHours( ) const
{
	return weeklyHours;
}

double Employee::getCalcPay( ) const
{
	if (weeklyHours <= WEEK_MAX)
	{
		netPay = hourlyWage * weeklyHours;
		fedTotal = netPay * FED_TAX;
		stateTotal = netPay * STATE_TAX;
		payCheck = ((netPay - fedTotal) - stateTotal);
	}
	else if (weeklyHours > WEEK_MAX)
	{
		overHours = weeklyHours - WEEK_MAX;
		regularPay = WEEK_MAX * hourlyWage;
		overPay = overHours * (hourlyWage * OVER_TIME);
		netPay = regularPay + overPay;
		fedTotal = netPay * FED_TAX;
		stateTotal = netPay * STATE_TAX;
		payCheck = ((netPay - fedTotal) - stateTotal);
	}
	return payCheck;
}

driver.cpp
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
55
56
57
58
59
60
61
#include <iostream>
#include <fstream>
#include "employee.h"

using namespace std;

// printCheck function
// Purpose: Create a paystub for an employee
// Parameters: Employee information
// Returns: void
void printCheck(const Employee&);

int main()
{
	Employee b1(1234, "Bruce Banner", "436 E 900 S", "801-465-2291", 10.00, 45);
	Employee b2(1569, "Tony Stark", "7000 E 9680 S", "801-941-0745", 12.50, 30);
	//open the file for output
	ofstream odataFile("employeeData.txt");
	if (odataFile.good())
	{
		//write the data
		b1.writeEmployee(odataFile);
		b2.writeEmployee(odataFile);
		odataFile.close();
	}
	// open the file to get input
	ifstream idataFile("employeeData.txt");
	if (idataFile.good())
	{
		// read the file
		if (b1.readEmployee(idataFile))
		{
			// if read was successfuL
			printCheck(b1);
			cout << '\n';
			printCheck(b2);
		}
		else // the read operation failed ... display a message
			cout << "\nRead failed" << endl;
			system("PAUSE");
	}
	//if the file couldn't open ... display message
	else
	{
		cout << "Open Failed" << endl;
		system("PAUSE");
	}
}

void printCheck(const Employee& b)
{
	cout << "--------------------Marvel Comics--------------------" << endl;
	cout << "Pay to the order of " << b.getEmployeeName( ) << "................" << b.getCalcPay( ) << endl;
	cout << "S.H.I.E.L.D Bank" << endl;
	cout << "-----------------------------------------------------";
	cout << "Hours worked: " << b.getWeeklyHours( ) << endl;
	cout << "Hourly Wage: " << b.getHourlyWage( ) << endl;
	cout << "\n" << endl;
	system("PAUSE");
	system("CLS");
}
In the driver at lines 15-16 the employee name is given as "Bruce Banner" and "Tony Stark".

That is, two words, separated by a space. However at line 40 in employee.cpp only a single word is extracted by input >> employeeName

The same applies to the employee address.

That means the readEmployee() function gets completely out of synchronisation with the data it is trying to read.

A possible solution is to modify the writeEmployee() function to use some other delimiter such as the tab or pipe character ('\t' or '|') in order to separate each field in the output file. A newline character after each record might be useful too.

Then you will have to modify the function which reads the data accordingly, probably by using getline() with the matching delimiter. But care will need to be taken with the numeric fields such as employeeNumber and hourlyWage, since they are not strings.

simple :-)

so you output "Bruce Banner" as name, and that's okay, but when you do input >> employeeName (remember that ">>" will be delimited by white space), you only get "Bruce", input >> employeeAddress will get "Banner", phoneNumber "436" and hourlyWage will be "E" and so on. Also there is no space between weeklyHours (45) of b1 and employeeNumber (1569) of b2, so you'll get "451569" for b1.weeklyHours. Plus, you're only reading one record ever, but printCheck()ing 2.
I haven't ever used another delimiter, it is hard for me to correct this error. I am not sure how to even get started with moving things around without the >> operator. I have done some research on the matter and I still am no closer to answering it.
This is what I tried, but it's not working.

driver.cpp line 15 edit
Employee b1(1234, "\tBruce Banner", "\t436 E 900 S", "\t801-465-2291", |10.00, |45);
employee.cpp line 53 edit
output << employeeNumber << '\t' << employeeName << '\t' << employeeAddress << '\t' << phoneNumber << '|' << hourlyWage << '|' << weeklyHours;
This is what I tried, but it's not working.
It isn't necessary to change the driver. The changes will be in readEmployee() and writeEmployee().


Changing the delimiter is pretty simple for the output:
1
2
3
4
5
6
7
8
9
10
11
void Employee::writeEmployee(std::ofstream& output)
{
    const char delim = '\t';

    output << employeeNumber  << delim 
           << employeeName    << delim 
           << employeeAddress << delim 
           << phoneNumber     << delim 
           << hourlyWage      << delim 
           << weeklyHours     << '\n';
}

though reading this data back in becomes, while not difficult, perhaps a little untidy, as the numeric and text fields need to be handled a little differently.

Or you might try a compromise - I don't necessarily recommend this, but it might be a possibility:
1
2
3
4
5
6
7
8
9
10
11
12
void Employee::writeEmployee(std::ofstream& output)
{
    const char delim = '\t';
    const char space = ' ';

    output << employeeNumber  << space 
           << employeeName    << delim 
           << employeeAddress << delim 
           << phoneNumber     << delim 
           << hourlyWage      << space 
           << weeklyHours     << '\n';
}


In order to read the text fields, instead of
input >> xxxx;
you would use
getline(input, xxxx, delim);
http://www.cplusplus.com/reference/string/string/getline/
Last edited on
Thanks for the reply Chervil! Here is what I have so far, I am still getting an error when I take your advice on the getline(). I am assuming that I cannot simply put those into an if statement, but that is where it needs corrected i believe.

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include "employee.h"

//Declaring constants
const int WEEK_MAX = 40;
const double FED_TAX = 0.20;
const double STATE_TAX = 0.075;
const double OVER_TIME = 1.5;
const char delim = '\t';
const char space = ' ';

//Declaring variables 
double netPay;
double fedTotal;
double stateTotal;
double payCheck;
double overHours;
double overPay;
double regularPay;

Employee::Employee()
{
	employeeNumber = 0;
	employeeName = "";
	employeeAddress = "";
	phoneNumber = "";
	hourlyWage = 0.00;
	weeklyHours = 0.00;
}

Employee::Employee(int eNumber, string eName, string eAddress, string pNumber, double hWage, double wHours)
{
	employeeNumber = eNumber;
	employeeName = eName;
	employeeAddress = eAddress;
	phoneNumber = pNumber;
	hourlyWage = hWage;
	weeklyHours = wHours;
}

bool Employee::readEmployee(ifstream& input)
{
	if (getline(input, employeeNumber, space) && getline(input, employeeName, delim) && getline(input, employeeAddress, delim) && getline(input, phoneNumber, delim) && getline(input, hourlyWage, space) && getline(input, weeklyHours, '\n'))
	{
		return true;
	}
	else
	{
		return false;
	}
}

void Employee::writeEmployee(ofstream& output)
{
	//No error checking when writing a file
	output << employeeNumber	<< space
		   << employeeName		<< delim
		   << employeeAddress	<< delim 
		   << phoneNumber		<< delim 
		   << hourlyWage		<< space
		   << weeklyHours		<< '\n';
}

int Employee::getEmployeeNumber( ) const
{
	return employeeNumber;
}

string Employee::getEmployeeName( ) const
{
	return employeeName;
}

string Employee::getEmployeeAddress( ) const
{
	return employeeAddress;
}

string Employee::getPhoneNumber( ) const
{
	return phoneNumber;
}

double Employee::getHourlyWage( ) const
{
	return hourlyWage;
}

double Employee::getWeeklyHours( ) const
{
	return weeklyHours;
}

double Employee::getCalcPay( ) const
{
	if (weeklyHours <= WEEK_MAX)
	{
		netPay = hourlyWage * weeklyHours;
		fedTotal = netPay * FED_TAX;
		stateTotal = netPay * STATE_TAX;
		payCheck = ((netPay - fedTotal) - stateTotal);
	}
	else if (weeklyHours > WEEK_MAX)
	{
		overHours = weeklyHours - WEEK_MAX;
		regularPay = WEEK_MAX * hourlyWage;
		overPay = overHours * (hourlyWage * OVER_TIME);
		netPay = regularPay + overPay;
		fedTotal = netPay * FED_TAX;
		stateTotal = netPay * STATE_TAX;
		payCheck = ((netPay - fedTotal) - stateTotal);
	}
	return payCheck;
}
I meant you should use getline for the text fields, that is these:
1
2
3
	string employeeName;
	string employeeAddress;
	string phoneNumber;


this won't work:getline(input, employeeNumber, space) as employeeNumber is of type int.

A more brute-force approach would be to read everything as though it was a string (using a temporary string for the numeric data), and then extract the numeric values using a stringstream. Not difficult, but the code starts to grow in length.







.


Last edited on
Thanks for your patience Chervil. I will use you advice for the 'string' variable specifically, and use 'input >>' for the int and double variables. My program works great now! Thanks to all for the help!!!!
Topic archived. No new replies allowed.