-2

A class I've been working on for a few days, running into an error I'm unsure how to fix.

#include <iostream>             // for cin, cout, endl
#include <string>
#include <iomanip>              // formatting floats

using namespace std;
    
void programHeader();
void footer();
void printEmployeeInfo(struct employeeInfo);

struct employeeInfo 
{
    int employeeID;
    char employeeName[20];
    double payRate;
    int employeeType;
};

float findGrossPay(employeeInfo myEmployee, double , int);
void payrollDisplay(employeeInfo myEmployee, double, double, double, float, float);

//prototype declerations

int main()
{
    // decleration of variables 
    float inputNumber1;
    int num1;
    int num2;
    int num3;
    int num4;
    employeeInfo myEmployee[4];
    float totalGross;
    float totalNet;
    int maxName = 20;
    int location;

    double hoursArray[4];
    double grossPay[4];
    double tax[4];
    double netPay[4];

    // input section
    programHeader();
    
    num4 = 0;
    location = 0;
    
    for (int c = 0; c < 4; c++)  // fill in the array of structs
    {
        while (true);            // validation loop
        {
            cout << "Employee ID: ";
            cin >> num1;
            if (num1 > 0);
            {
                myEmployee[c].employeeID = num1;
                break;
            } // end if
            if (num1 <= 0)
            {
                cout << "\nERROR PLEASE TRY AGAIN" << endl;
            } // end else if
        } // end while
        cout << "Employee Name: ";
        cin.getline(myEmployee[c].employeeName, maxName);

        while (true);             // validation loop
        {
            cout << "Pay rate: ";
            cin >> num2;
            if (num2 > 0);
            {
                myEmployee[c].payRate = num2;
                break;
            } // end if
            if (num2 <= 0)
            {
                cout << "\nERROR PLEASE TRY AGAIN" << endl;
            } // end if
        } // end while

        while (true)            // validation loop
        {
            cout << "Type: ";
            cin >> num3;
            if ((num3 == 1) || (num3 == 0))
            {
                myEmployee[c].employeeType = num3;
                break;
            } // end if
            else
            {
                cout << "\nERROR PLEASE TRY AGAIN" << endl;
            } // end else

        } // end while 
    } // end for(c)

    for (int h = 0; h < 4; h++);            // parallel array to hold hours worked
    {
        
        cout << "Hours worked for " << myEmployee[num4].employeeName << ": ";
        cin >> hoursArray[num4];
        num4 = num4 +1;
    } // end for(h)

    // calculation section
   
    
    // displays the results
    
    for (int l = 0; l < 4; l++)             // l for location
    {
        grossPay[l] = findGrossPay(myEmployee[4], hoursArray[4], location);
        location = location + 1;
    } // end for(l)

    for (int t = 0; t < 4; t++)        // get taxes and net pay for each
    {
        tax[t] = grossPay[t] * (15 / 100);
        netPay[t] = grossPay[t] - tax[t];
    }
    
    for (int i = 0; i < 4; i++)
    {
        totalGross = totalGross + grossPay[i];
        totalNet = totalNet + netPay[i];
    } // end of for

    payrollDisplay(myEmployee[4], grossPay[4], tax[4], netPay[4], totalGross, totalNet);

    footer();

    system("PAUSE");
    return 0;
    
}// end of main

float findGrossPay(employeeInfo myEmployee[4], double hoursArray[4], int l)             // l stands for location
{
    float numGrossPay;

    if (myEmployee[l].employeeType == 1)            // management
    {
        numGrossPay = myEmployee[l].payRate * hoursArray[l]; 
    } // end if
    else if (myEmployee[l].employeeType == 0)           // union members
    {
        if (hoursArray[l] > 40)
        {
            numGrossPay = myEmployee[l].payRate * 40 + (hoursArray[l] - 40) * (myEmployee[l].payRate * 1.5);
        } // end if
        else
        {
            numGrossPay = myEmployee[l].payRate * hoursArray[l];
        } // end else
    } // end else if

    return numGrossPay;
}

void payrollDisplay(employeeInfo myEmployee[4], double grossPay[4], double tax[4], double netPay[4], float totalGross, float totalNet)
{
    cout << "------------------------------------------------------------" << endl;
    cout << "\nPayroll Report\n" << endl;
    cout << "ID \tName" << "\t\tGross Pay \tTax \tNet Pay" << endl;
    
    for (int i = 0; i < 4; i++)             // to print each employee
    {
        cout << myEmployee[i].employeeID << "\t" << myEmployee[i].employeeName << "\t\t" << grossPay[i]
            << "\t" << tax[i] << "\t" << netPay[i] << endl;
    } // for(i) 

    cout << "\nTotal Gross Pay \t$" << totalGross << endl;
    cout << "Total Net Pay \t$" << totalNet << endl;
}

It's giving me an error stating there is an undefined reference to these lines in main():

grossPay[l] = findGrossPay(myEmployee[4], hoursArray[4], location);

and

payrollDisplay(myEmployee[4], grossPay[4], tax[4], netPay[4], totalGross, totalNet);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Rachel
  • 11
  • 1
  • Compare the declaration: `float findGrossPay(employeeInfo myEmployee, double , int);` with the actual function definition. You really don't see the major, glaring, difference? – Sam Varshavchik Apr 14 '22 at 23:18
  • 1
    When I've got a problem like this I paste the implementation underneath the definition and deploy the ol' Mark I eyeball to scan for differences. Note: You could have avoided the problem entirely by placing `main` at the bottom of the file and getting rid of the forward declarations. If you declare everything so that the first use is after the definition, you don't need declarations and have one less thing that can go wrong. – user4581301 Apr 14 '22 at 23:24

1 Answers1

0

The "undefined reference" errors are because your function declarations do not match their definitions.

You have declared findGrossPay() and payrollDisplay() as taking in a single employeeInfo and related values for that one employee, but then your definitions are taking in arrays of employees and values:

//declaration
float findGrossPay(employeeInfo myEmployee, double , int);

//definition
float findGrossPay(employeeInfo myEmployee[4], double hoursArray[4], int l)
// declaration
void payrollDisplay(employeeInfo myEmployee, double, double, double, float, float);

//definition
void payrollDisplay(employeeInfo myEmployee[4], double grossPay[4], double tax[4], double netPay[4], float totalGross, float totalNet)

As such, the linker can't find matching definitions for the functions you are actually calling.

And, to make that worse, the places where you are calling these functions are accessing array elements out of bounds, which is undefined behavior.

After you fix that problem, you should then get "undefined reference" errors for programHeader() and footer(), since their definitions are missing completely.

After fixing that, there are still other problems with your code:

  • you have a number of if and for/while loops that have an erroneous ; on them
  • you are accessing arrays incorrectly in some places
  • you have uninitialized variables in some of your calculations

With that said, try something more like this:

#include <iostream>             // for cin, cout, endl
#include <string>
#include <iomanip>              // formatting floats
#include <limits>

using namespace std;
    
struct employeeInfo 
{
    int employeeID;
    string employeeName;
    double payRate;
    int employeeType;
};

//prototype declerations
void programHeader();
void footer();
int promptForNumber(const string &prompt, int minValue = 0, int maxValue = numeric_limits<int>::max());
string promptForString(const string &prompt);
float findGrossPay(const employeeInfo &myEmployee, double hours);
void payrollDisplay(const employeeInfo myEmployee[4], const double grossPay[4], const double tax[4], const double netPay[4]);

int main()
{
    // decleration of variables 
    employeeInfo myEmployee[4];
    double hours[4];
    double grossPay[4];
    double tax[4];
    double netPay[4];
    int num;

    // input section
    programHeader();

    for (int c = 0; c < 4; c++)  // fill in the array of structs
    {
        myEmployee[c].employeeID   = promptForNumber("Employee ID", 1);
        myEmployee[c].employeeName = promptForString("Employee Name");
        myEmployee[c].payRate      = promptForNumber("Pay rate", 1);
        myEmployee[c].employeeType = promptForNumber("Type", 0, 1);
    }

    for (int h = 0; h < 4; h++)            // parallel array to hold hours worked
    {
        hours[h] = promptForNumber("Hours worked for " << myEmployee[h].employeeName);
    }

    // calculation section
   
    for (int l = 0; l < 4; l++)             // l for location
    {
        grossPay[l] = findGrossPay(myEmployee[l], hours[l]);
    }

    for (int t = 0; t < 4; t++)        // get taxes and net pay for each
    {
        tax[t] = grossPay[t] * (15 / 100);
        netPay[t] = grossPay[t] - tax[t];
    }
    
    // displays the results
    payrollDisplay(myEmployee, grossPay, tax, netPay);

    footer();

    system("PAUSE");
    return 0;    
}

void programHeader()
{
    // print out something here...
}

void footer()
{
    // print out something here...
}

int promptForNumber(const string &prompt, int minValue, int maxValue)
{
    int num;

    while (true)            // validation loop
    {
        cout << prompt << ": ";

        if (cin >> num)
        {
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            if ((num >= minValue && num <= maxValue)
                break;
        }
        else
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }

        cout << "\nERROR PLEASE TRY AGAIN" << endl;
    }

    return num;
}

string promptForString(const string &prompt)
{
    string input;

    while (true)             // validation loop
    {
        cout << prompt << ": ";

        if (getline(cin, input) && !input.empty())
            break;

        cout << "\nERROR PLEASE TRY AGAIN" << endl;
    }

    return input;
}

float findGrossPay(const employeeInfo &myEmployee, double hours)
{
    if (myEmployee.employeeType == 1)            // management
    {
        return myEmployee.payRate * hours; 
    }

    // must be myEmployee.employeeType == 0      // union members
    if (hours > 40)
    {
        return myEmployee.payRate * 40 + (hours - 40) * (myEmployee.payRate * 1.5);
    }
    else
    {
        return myEmployee.payRate * hours;
    }
}

void payrollDisplay(const employeeInfo myEmployee[4], const double grossPay[4], const double tax[4], const double netPay[4])
{
    float totalGross = 0.0f;
    float totalNet = 0.0f;

    cout << "------------------------------------------------------------" << endl;
    cout << "\nPayroll Report\n" << endl;
    cout << "ID \tName" << "\t\tGross Pay \tTax \tNet Pay" << endl;
    
    for (int i = 0; i < 4; i++)             // to print each employee
    {
        cout << myEmployee[i].employeeID << "\t" << myEmployee[i].employeeName << "\t\t" << grossPay[i] << "\t" << tax[i] << "\t" << netPay[i] << endl;
        totalGross += grossPay[i];
        totalNet += netPay[i];
    }

    cout << "\nTotal Gross Pay \t$" << totalGross << endl;
    cout << "Total Net Pay \t$" << totalNet << endl;
}

That said, you might consider moving the hours/grossPay/tax/netPay values into the employeeInfo struct, so that you have to manage only 1 array and not 5 parallel arrays.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770