1

Good day

I have written a code that outputs a payslip for an employee.

Also despite doing lots of research (i have tried to figure it out on my own) I am not sure how to get my for loop to allow me to consecutively enter information for 5 different employees on the same output screen. When i run the program it allows me to enter all the information for the pay slip except the name of the employees at the beginning of each new pay slip.

I am a beginner wanting to learn as much as possible so any explanation would be greatly appreciated.

My code is as follows:

#include <iostream>
#include <string>

using namespace std;

void getData (string & theEmployee , float & theHoursWorked, float & 
thePayRate)
{
  cout<< "Enter the employees name and surname: "<< endl;
  getline(cin, theEmployee);

  cout << "Enter the numbers of hours the employee worked: " << endl;
  cin >> theHoursWorked;

  cout << "Enter the employees hourly pay rate?" << endl;
  cin >> thePayRate;

}

  float calculatePay(const string & theEmployee, float theHoursWorked, float 

  thePayRate)
{
  float regularPay, thePay, overtimeHours;
  if (theHoursWorked > 40)
{
 regularPay = 40 * thePayRate;
 overtimeHours = theHoursWorked - 40;
 thePay = regularPay + (overtimeHours * 1.5 * thePayRate);
 return thePay
}
else
thePay = theHoursWorked * thePayRate;
return thePay;
}

void printPaySlip(const string & theEmployee, float theHoursWorked, float
thePayRate, float thePay)
{
float overtimeHours;
 cout << "Pay slip for " << theEmployee <<endl;
 cout << "Hours worked: "<< theHoursWorked << endl;
 if (theHoursWorked > 40)
 overtimeHours = theHoursWorked - 40;
 else
 overtimeHours = 0;
 cout << "Overtime hours: "<< overtimeHours << endl;
 cout << "Hourly pay rate: " << thePayRate << endl;
 cout << "Pay: " << thePay << endl;
 cout << endl;

}


 int main()
{
 string theEmployee;
 float theHoursWorked;
 float thePayRate;
 int thePay;

 for (int i = 0; i < 5; i++)
{
  getData(theEmployee, theHoursWorked, thePayRate);
  thePay = calculatePay (theEmployee, theHoursWorked, thePayRate);
  printPaySlip(theEmployee, theHoursWorked, thePayRate, thePay);
}

return 0;
}
Geo
  • 31
  • 6
  • 2
    mixing getline and cin >> int, see http://stackoverflow.com/questions/5739937/using-getlinecin-s-after-cin or short form, try putting this at the end of getData: cin.ignore(std::numeric_limits::max(), '\n'); – Kenny Ostrom Apr 09 '17 at 20:00
  • if i use the getline under the other two it says that there is an error – Geo Apr 09 '17 at 20:07
  • how would i correctly declare that though? – Geo Apr 09 '17 at 20:27

2 Answers2

0

You can see the standard input of your program as a continuous stream of characters.

For example, my stdin will contain the following text:

Alice\n
2\n
3\n
Bob\n
3\n
2\n
Charlie\n
1\n
1\n

Note that at the end of line there will be an end-of-line character (EOL or \n in C++).

The first call to std::getline() will return the first name Alice and will stop at the EOL, not including that in the output. All is well.

The next call to cin >> theHoursWorked will read the 2 into the variable and all is well. But it will not consume the EOL because it is not part of the number.

The next call to cin >> thePayRate will skip the EOL, because it is not a number, and it will read the 3. It will not consume the next EOL either.

But then, the next call to std::getline() will find a EOL character just as the first character and it will return an empty string.

The next call to cin >> theHoursWorked will find the B from Bob and it will fail badly. From now on, you will not get the expected input.

The solution is to properly skip the EOL characters, and any other whitespace, when needed. There are several ways to do that.

  1. Call std::getline() with a dummy string variable just after cin >> theHoursWorked.
  2. Call cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); to skip the remaining characters up to the EOL, included`.
  3. Read all the data from cin using std::getline() and then convert the string to a double in a second call: getline(cin, line); std::istringstream(line) >> theHoursWorked;.
rodrigo
  • 94,151
  • 12
  • 143
  • 190
  • Ok thank you. I am starting to get it. how would i declare the std::getline() function though? and can i ask what you mean by a dummy string? – Geo Apr 09 '17 at 20:26
  • @Geo: Just do `string dummy; getline(cin, dummy);` and done. I call that variable dummy because its value is not used after getting assigned. – rodrigo Apr 09 '17 at 20:36
  • thank you so much, my code is now working correctly. Thank you for taking the time to explain it to me! – Geo Apr 09 '17 at 20:50
  • @Geo: No problem, that's what SO is for. If you think that the answer is ok, do not forget to accept and/or upvote it. – rodrigo Apr 09 '17 at 21:00
0

There are 2 solutions I can see: adding a cin.ignore(); line to the end of the getData function should solve the problem. OR change getline to getline(cin>>std::ws, theEmployee);

cin by default skips all whitespace (spaces, tabs, new lines, etc.), so in a multiple cin line program, if a user presses 'enter' in a previous cin command, that newline is ignored and the cin will correctly extract the data you want.

After the first loop of getData, a newline '\n' is left on the standard input buffer (from the user entering the information of thePayRate). However, the getline command will NOT skip this newline character left on the input buffer. In fact, it immediately terminates when it sees a newline character (hence getline), returning an empty string. To force the getline command to ignore this whitespace use getline(cin>>std::ws, ...). Alternatively, you can use cin.ignore() to deal with this newline character left in the standard input buffer.

jorjor17
  • 21
  • 3