Help w/ input validation in function arrays

I'm having a couple of problems w/ getting the program to end when the user enters 'Q' after they've been asked if they want to try again. Also, after enter a negative int is entered for employee id then either the program moves to displayEmployeeInfo & shows the info that's been already entered or if no info had been entered it should skip displayEmployeeInfo altogether and just display the total payroll at zero. Sorry if I'm not explaining this well but here are the samples:

Sample Run:

Enter employee ID ====> -5

Total Payroll for this month: $0.00

Sample Run #3:

Enter employee ID ====> 123
Enter payroll status ====> t
*** Invalid payroll status ***
Do you want to try again or quit?
Type Q or q to quit, any other key to continue: U
Re-enter: 's' or 'S' for salaried, 'h' or 'H' for hourly,
'c' or 'C' for commissioned ====> x

*** Invalid payroll status ***
Do you want to try again or quit?
Type Q or q to quit, any other key to continue: x
Re-enter: 's' or 'S' for salaried, 'h' or 'H' for hourly,
'c' or 'C' for commissioned ====> H
Enter number of hours worked this month ====> 160

Enter employee ID ====> -9

Employee ID Payroll Status Gross Pay

123 Hourly $3000


Total Payroll for this month: $3000.00

[code]
#include
#include
using namespace std;
#include

int getEmployeeData (int[], char[], int, float[]);
float calculateGrossPay(char[], float[], int, float[], string[], float*);
void displayEmployeeInfo (int[], string[], int, float[]);
bool tryAgain (char);
bool isValidStatus (char);
//bool isValidID (int);

int main()
{
const int numEmp = 4;
int empId[numEmp], size;
char payrollStat[numEmp];
float gross[numEmp];
float pay[numEmp];
float totalPay = 0;
string nameStatus[numEmp];

size = numEmp;

getEmployeeData(empId, payrollStat, size, gross);
calculateGrossPay(payrollStat, gross, size, pay, nameStatus, &totalPay);
cout << fixed << showpoint << setprecision(2);
displayEmployeeInfo (empId, nameStatus, size, pay);

cout << "
Total Payroll for this month: " << "$" << totalPay << endl;

system("pause");

return 0;
}

int getEmployeeData (int e[], char ps[], int numEmp, float amt[])
{
bool vStat;
bool tAgain;
char q;
int x;

for (x = 0; x < numEmp; x++)
{
cout << "Enter employee ID ====> ";
cin >> e[x];

if(e[x] < 0)
return ; // Not sure what I should be returning here
else
{
cout << "Enter payroll status (s/h/c)====> ";
cin >> ps[x];
ps[x] = toupper(ps[x]);

vStat = isValidStatus(ps[x]);
if(vStat == false)
{
do
{
cout << "*** Invalid payroll status ***
";
cout << "Do you want to try again or quit?
";
cout << "Type Q or q to quit, any other key to continue: ";
cin >> q;
q = toupper(q);

tAgain = tryAgain(q);

if(tAgain == false)
{
cout << " Re-enter: 's' or 'S' for salaried, 'h' or 'H' for hourly,
";
cout << " 'c' or 'C' for commissioned ====> ";
cin >> ps[x];
ps[x] = toupper(ps[x]);
vStat = isValidStatus(ps[x]);
}

}while (vStat == false && q != 'Q');
}

if(vStat == true)
{
if (ps[x] == 'S')
{
cout << "Enter monthly salary ====> ";
}
else if (ps[x] == 'H')
{
cout << "Enter number of hours worked this month ====> ";
}
else if (ps[x] == 'C')
{
cout << "Enter total sales for this month ====> ";
}

cin >> amt[x];

cout << "
";
}
}
}
return amt[x];
}

float calculateGrossPay (char pStat[], float pay[] , int numEmp, float tot[], string nStat[], float* totalP)
{
int y;
for (y = 0; y < numEmp; y++)
{
if (pStat[y] == 'S')
{
nStat[y] = "Salaried";
tot[y] = pay[y];
*totalP += tot[y];
}
if (pStat[y] == 'H')
{
nStat[y] = "Hourly";
tot[y] = pay[y] * 18.75;
*totalP += tot[y];
}
if (pStat[y] == 'C')
{
nStat[y] = "Commissioned";
tot[y] = (pay[y] * 0.06) + 1000.00;
*totalP += tot[y];
}
}
return *totalP;
}

void displayEmployeeInfo (int id[], string payS[], int numEmp, float gPay[])
{
cout << "Employee ID " << " Payroll Status " << " GrossPay
";
cout << "___________ " << " ______________ " << " ________
";
for (int z = 0; z < numEmp; z++)
{
cout << id[z] << " " << payS[z] << " " << "$" << gPay[z] << endl;
}
}

bool isValidStatus (char stat)
{
if(stat == 'S' || stat == 'H' || stat == 'C')
return true;
else
return false;
}

bool tryAgain (char q)
{
if(q == 'Q')
return true;
else
return false;
}
[/code]

Any help woould be greatly appreciated

Comments

  • [code]
    #include
    #include
    using namespace std;
    #include

    int getEmployeeData (int[], char[], int, float[]);
    float calculateGrossPay(char[], float[], int, float[], string[], float*);
    void displayEmployeeInfo (int[], string[], int, float[]);
    bool tryAgain (char);
    bool isValidStatus (char);
    //bool isValidID (int);

    [color=Green]//
    // The main idea of these two following functions is to
    // validate the text entered by user and then convert that
    // to a proper numeric value using atoi() function to
    // convert to an integer and atof() - to convert to a float.
    // Basically, user enters text at first.
    //[/color]
    int IsValidFloat(const char text[])
    {
    int nDots=0;
    char c;
    [color=Green]//
    // Examine each character within text
    //[/color]
    while ((c = *text++) != 0)
    {
    [color=Green]//
    // Count the decimal period characters
    //[/color]
    if (c == '.') ++nDots;
    [color=Green]//
    // Non-digit character means invalid input
    //[/color]
    else if ((c < '0') || (c > '9')) return 0;
    }
    return (nDots < 2);
    }

    int IsValidInteger(const char text [])
    {
    string s (text); [color=Green]// Construct a string object out of text[/color]
    [color=Green]//
    // Re-use the float validator and just check if value
    // has a decimal period and if it has - then text is not valid.
    // There should be only digits to indicate an integer.
    //[/color]
    return (IsValidFloat (text) && (s.find ('.') == string::npos));
    }

    [color=Green]//
    // Using these two validators we can write a common function
    // to enter both types of values.
    //
    // prompt: text to print before input is entered
    // IResult: address of integer value to enter
    // (pass NULL if float value needed)
    // FResult: address of float value to enter
    // (pass NULL if integer value needed)
    //
    // Do not pass NULL for both IResult and FResult!
    // This will force the code into endless loop!
    //[/color]
    void AskNumericValue (char* prompt, int* IResult, float* FResult)
    {
    string value;
    while (prompt) [color=Green]// loop until poor user enters valid value[/color]
    {
    [color=Green]//
    // Ask the question and get the text
    //[/color]
    cout << prompt;
    cin >> value;
    [color=Green]//
    // If integer wanted - verify and convert as integer
    //[/color]
    if (IResult)
    {
    if (! IsValidInteger (value.c_str ()))
    {
    cout << "
    -- Please enter integer value.
    ";
    continue; [color=Green]// <-- go back to enter a while() block again[/color]
    }
    *IResult = atoi (value.c_str ());
    return; [color=Green]// Done with int value[/color]
    }
    [color=Green]//
    // Same for float
    //[/color]
    if (FResult)
    {
    if (! IsValidFloat (value.c_str ()))
    {
    cout << "
    -- Please enter float point value.
    ";
    continue;
    }
    *FResult = (float) atof (value.c_str ());
    [color=Green]//
    // atof() returns double, thus it is ^^^ converted to float
    //[/color]
    return;
    }
    }
    }

    int main()
    {
    const int numEmp = 4;
    int empId[numEmp], size;
    char payrollStat[numEmp];
    float gross[numEmp];
    float pay[numEmp];
    float totalPay = 0;
    string nameStatus[numEmp];

    size = numEmp;

    getEmployeeData(empId, payrollStat, size, gross);
    [color=Green]//
    // Return value up here ^^^ is lost. The value you
    // calculated is returned by 'gross'.
    //[/color]
    calculateGrossPay(payrollStat, gross, size, pay, nameStatus, &totalPay);
    cout << fixed << showpoint << setprecision(2);
    displayEmployeeInfo (empId, nameStatus, size, pay);

    cout << "
    Total Payroll for this month: " << "$" << totalPay << endl;

    system("pause");

    return 0;
    }

    int getEmployeeData (int e[], char ps[], int numEmp, float amt[])
    {
    bool vStat;
    bool tAgain;
    char q;
    int x;
    [color=Green]//
    // Arrays need to be cleared, so if user quits - proper
    // calculations are done.
    //[/color]
    for (x = 0; x < numEmp; x++)
    {
    ps[x] = 'Q';
    e[x] = 0;
    amt[x] = 0;
    }

    for (x = 0; x < numEmp; x++)
    {
    [color=Green]//cout << "Enter employee ID ====> ";
    //cin >> e[x];[/color]
    AskNumericValue ("Enter employee ID ====> ", &e[x], NULL);

    cout << "Enter payroll status (s/h/c)====> ";
    cin >> ps[x];
    ps[x] = toupper(ps[x]);
    [color=Green]//
    // This ^^^ (passing a char to cin) is not good. Try
    // To enter something like "sss" and you will see that
    // some of following inputs are 'swallowed' by cin.
    // You need to enter a string and then transfer the
    // 1st character into ps[x]. Before the transfer you
    // need to verify that string is indeed "S","H" or "C".
    //[/color]
    vStat = isValidStatus(ps[x]);
    if(vStat == false)
    {
    do
    {
    cout << "*** Invalid payroll status ***
    ";
    cout << "Do you want to try again or quit?
    ";
    cout << "Type Q or q to quit, any other key to continue: ";
    cin >> q;
    q = toupper(q);
    [color=Green]//
    // The 'other key to continue' is kind
    // of asking to press spacebar. Try it.
    // cin ignores empty space (tabs or blanks).
    //[/color]
    tAgain = tryAgain(q);

    if(tAgain == false)
    {
    cout << " Re-enter: 's' or 'S' for salaried, 'h' or 'H' for hourly,
    ";
    cout << " 'c' or 'C' for commissioned ====> ";
    cin >> ps[x];
    ps[x] = toupper(ps[x]);
    vStat = isValidStatus(ps[x]);
    }

    }while (vStat == false && q != 'Q');
    [color=Green]//
    // Quit the for() loop
    //[/color]
    if (q == 'Q') break;
    }

    if(vStat == true)
    {
    char* prompt;
    if (ps[x] == 'S')
    {
    [color=Green]//cout << "Enter monthly salary ====> ";[/color]
    prompt = "Enter monthly salary ====> ";
    }
    else if (ps[x] == 'H')
    {
    [color=Green]//cout << "Enter number of hours worked this month ====> ";[/color]
    prompt = "Enter number of hours worked this month ====> ";
    }
    else if (ps[x] == 'C')
    {
    [color=Green]//cout << "Enter total sales for this month ====> ";[/color]
    prompt = "Enter total sales for this month ====> ";
    }

    [color=Green]//cin >> amt[x];[/color]
    AskNumericValue (prompt, NULL, &amt[x]);
    cout << "
    ";
    }
    }
    [color=Green]//return (int) amt[x]; // Why return it if never used?
    //
    // Also, the compiler shows the loss of data up here ^^^, because
    // the return type is int and amt[x] is float, so if you return
    // 3762.94 - you get 3762 from the function, so .94 is lost. But,
    // the returned value is not used anyway - just FYI.
    //
    // P.S. Another problem here -- 'x' reached a value of 4 now, because
    // for() loop ended, so amt[x] is returning a value beyond the last
    // value in that array - the last valid index for the array is 3.
    // I will simply return 0 here - it is not used anyway.[/color]
    return 0;
    }

    float calculateGrossPay (char pStat[], float pay[] , int numEmp, float tot[], string nStat[], float* totalP)
    {
    int y;
    *totalP = 0; // Clear total
    for (y = 0; y < numEmp; y++)
    {
    if (pStat[y] == 'Q') break; [color=Green]// Do not calc more if 'Q' encountered[/color]

    if (pStat[y] == 'S')
    {
    nStat[y] = "Salaried ";
    tot[y] = pay[y];
    *totalP += tot[y];
    }
    if (pStat[y] == 'H')
    {
    nStat[y] = "Hourly ";
    tot[y] = pay[y] * 18.75f; // <-- float constants must have 'f'
    *totalP += tot[y];
    }
    if (pStat[y] == 'C')
    {
    nStat[y] = "Commissioned";
    tot[y] = (pay[y] * 0.06f) + 1000.00f;
    *totalP += tot[y];
    }
    }
    return *totalP;
    }

    void displayEmployeeInfo (int id[], string payS[], int numEmp, float gPay[])
    {
    cout << "Employee ID " << "Payroll Status " << "GrossPay
    ";
    cout << "----------- " << "-------------- " << "--------
    ";
    for (int z = 0; z < numEmp; z++)
    {
    if (id[z] == 0) break; [color=Green]// In case of quitting[/color]
    cout << id[z] << " " << payS[z] << " " << "$" << gPay[z] << endl;
    }
    }

    bool isValidStatus (char stat)
    {
    if(stat == 'S' || stat == 'H' || stat == 'C')
    return true;
    else
    return false;
    }

    bool tryAgain (char q)
    {
    if(q == 'Q')
    return true;
    else
    return false;
    }
    [/code]
  • Thanks for your help but we're not allowed to use break or continue statements. Also some of the code (like the atoi function) used seems to be beyond what we've learned so far so I wouldn't be able to use it.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories