// Title: A Simple Payroll Program -- // Using Arrays and Functions // // Programmer: Bill McQuain // ID Number: 000-00-0000 // Compiler: Microsoft Visual C++ ver 4.0 // Platform: Pentium 120, Windows 95 // Date: November 7, 1996 // // Purpose: // // This program reads information about a group of employees // from an input file named "inpay.dat": // // - ID number // - age // - gross monthly salary // - insurance plan type // // and computes the correct deductions for: // // - federal income tax // - social security tax // - insurance fee // - net monthly salary. // // It then prints out a labeled table of results, showing for // each employee the ID number, gross salary, insurance fee, // income and social security tax deductions and net salary. // In addition, the averages of each category are computed and // printed. // // The key to data organization is that a collection of // "parallel" arrays is used to store information about the // employees. By "parallel" I mean that array elements with // the same index will hold information about the same employee. // // Other changes (from funcpay.cpp): // // - The overall structure of main() is now divided into // logical sections: // - declarations // - function call to read data // - function call to calculate taxes, insurance, // net pay // - function call to print the table, including // header and averages // // - The input file is needed only by the function ReadData() // and the output file is needed only by the function // PrintTable() and the functions PrintHeader() and // CalcAvgs(), which are called by PrintTable(). Therefore, // the input and output file stream variables are made local // to ReadData() and PrintTable() respectively. // #include #include const int MaxEmp = 20; // maximum number of employees // Function prototypes. It's not necessary to include names for // the parameters here, but I recommend it because it helps keep // things straight. float FedTax(float EmpGrossPay); float Insurance(char EmpInsPlan, int EmpAge); void PrintHeader(ofstream& outPay); void ReadData(int IdNum[], float GrossPay[], int Age[], char InsPlan[], int& NumEmp); void CalcData(const float GrossPay[], const int Age[], const char InsPlan[], float InsFee[], float FIT[], float SSI[], float NetPay[], int NumEmp); void PrintTable(const int IdNum[], const float GrossPay[], const float InsFee[], const float FIT[], const float SSI[], const float NetPay[],int NumEmp); void CalcAvgs(ofstream& outPay, const float GrossPay[], const float InsFee[], const float FIT[], const float SSI[], const float NetPay[], int NumEmp); ////////////////////////////////////////////////////////////////////// // Beginning of main function: // int main() { // Local variables for main(): int IdNum[MaxEmp], // employee ID number Age[MaxEmp], // employee age NumEmp; // number of employees float GrossPay[MaxEmp], // employee gross pay NetPay[MaxEmp], // employee net pay SSI[MaxEmp], // employee SS tax FIT[MaxEmp], // employee income tax InsFee[MaxEmp]; // employee insurance fee char InsPlan[MaxEmp]; // employee insurance plan // Read employee data from input file: ReadData(IdNum, GrossPay, Age, InsPlan, NumEmp); // Calculate employee withholding data and net pay: CalcData(GrossPay, Age, InsPlan, InsFee, FIT, SSI, NetPay, NumEmp); // Print the table of employee information: PrintTable(IdNum, GrossPay, InsFee, FIT, SSI, NetPay, NumEmp); return NumEmp; } ////////////////////////////////////////////////////////////////////// // The function ReadData reads employee data from the input file and // stores it in the array parameters. ReadData will read until the // end of the input file or until the arrays are filled (determined // by the global constant MaxEmp). // // Output parameters (passed by reference): // // IdNum[] list of employee ID numbers // GrossPay[] list of gross pay amounts // Age[] list of employee ages // InsPlan[] list of insurance plan codes // NumEmp number of employees for whom data was stored // // Remember: An array parameter is passed by reference by default, // so no ampersands (&) are needed for them. // // Also note: We don't need to specify the dimension of an array // parameter in the function definition (or in the // prototype). But you do need to indicate that it's an // array; that's the reason for the []s. // // ReadData must be able to handle the situation where there are // more lines of input data than will fit into the arrays. This // is done by using two mechanisms. First, the loop control for // the while includes both a check for a read failure and a check // to be sure that we're not about to try to store values past the // end of the arrays. Second, we read the input values into local // variables first, then transfer them to the arrays only if the // array index is valid (MaxEmp - 1 or less). // // One point that may be confusing. The local variable Index is // used to keep track of which array locations are to be stored // into next. When we exit the while loop, Index will point to the // first unfilled location in the arrays. However, Index will equal // the number of employees whose records were stored into the // arrays. Remember that in C++ we index arrays starting at 0 // instead of 1. // void ReadData(int IdNum[], float GrossPay[], int Age[], char InsPlan[], int& NumEmp) { int Index = 0; // next array location to fill int empnum, // temp storage for employee id number empage; // employee age, float gross; // gross pay, and char plan; // insurance plan code ifstream inPay; // input file stream inPay.open("inpay.dat"); // open input file // Read first line of data from input file: inPay >> empnum >> empage >> gross >> plan; // Process and read next line until there's no more data or // we've filled up the arrays: while (inPay && Index < MaxEmp) { inPay.ignore(200, '\n'); // Skip to next line. IdNum[Index] = empnum; // Store the last input line Age[Index] = empage; // in the relevant arrays GrossPay[Index] = gross; InsPlan[Index] = plan; inPay >> empnum >> empage >> gross >> plan; Index++; // Update index for next store } NumEmp = Index; // Remember: we never stored anything // after the last increment of Index inPay.close(); // Close the input file. } ///////////////////////////////////////////////////////////////////// // CalcData is used to calculate the net pay amounts for all // employees. // // Input Parameters (passed by value): // // GrossPay[] list of gross pay amounts // Age[] list of employee ages // InsPlan[] list of insurance plan codes // NumEmp number of employees to be processed // // Note: to pass array parameters by value we specify their type // using "const" --- both in the definition and in the // prototype. This is really "pass by constant reference" // as we'll discuss in class. For practical purposes, the // effect is the same as pass by value. // // Output Parameters (passed by reference): // // InsFee[] list of insurance fees // FIT[] list of federal income taxes // SSI[] list of social security taxes // NetPay[] list of net pay amounts // void CalcData(const float GrossPay[], const int Age[], const char InsPlan[], float InsFee[], float FIT[], float SSI[], float NetPay[], int NumEmp){ const float SSRate = 0.0675f; // SSI tax rate ////////////////////////////////////////////////////////////// // Calculate the insurance fee, income tax, social security // tax and net pay for each employee, storing the results in // the relevant arrays: // for (int count = 0; count < NumEmp; count++) { InsFee[count] = Insurance(InsPlan[count], Age[count]); FIT[count] = FedTax(GrossPay[count]); SSI[count] = SSRate * GrossPay[count]; NetPay[count] = GrossPay[count] - FIT[count] - SSI[count] - InsFee[count]; } } ///////////////////////////////////////////////////////////////////// // Insurance is used to calculate the proper insurance fee for an // employee. // // Input Parameters (passed by value): // // InsPlan character 'B' or 'D', indicating plan selected // Age employee's age // // Return value: // // InsFee insurance fee charged to employee // float Insurance(char InsPlan, int Age) { const float HiPlanB = 225.00f; // constants for insurance fees const float MidPlanB = 150.00f; const float LoPlanB = 100.00f; const float HiPlanD = 300.00f; const float MidPlanD = 200.00f; const float LoPlanD = 140.00f; const char PlanB = 'B'; // constants for plan types const char PlanD = 'D'; float InsFee= 0.0f; // insurance fee charged switch (InsPlan) { // Calculate insurance fee case 'B':{if (Age <= 35) // for Plan B InsFee = LoPlanB; else if (Age <= 65) InsFee = MidPlanB; else InsFee = HiPlanB; break; } case 'D':{if (Age <= 35) // for Plan D InsFee = LoPlanD; else if (Age <= 65) InsFee = MidPlanD; else InsFee = HiPlanD; break; } } return InsFee; } ///////////////////////////////////////////////////////////////////// // FedTax is used to calculate the proper income tax for an employee. // // Input Parameter (passed by value): // // GrossPay employee's gross pay amount // // Return value: // // FIT income tax withheld for employee // float FedTax(float GrossPay) { const float HiTax = 0.33f; // constants for tax rates const float MidTax = 0.28f; const float LoTax = 0.15f; const float HiIncome = 3000.00f; // constants for income levels const float MidIncome = 1000.00f; float FIT = 0.0f; // variable for income tax if (GrossPay >= HiIncome) { // Determine FIT amount. FIT = HiTax*GrossPay; } else if (GrossPay >= MidIncome) { FIT = MidTax*GrossPay; } else { FIT = LoTax*GrossPay; } return FIT; } ///////////////////////////////////////////////////////////////////// // PrintHeader is used to print header for output file. // // Output Parameter (passed by reference): // // outPay output file stream variable // // The function does need to modify this stream (by inserting to // it), so the parameter must be passed by reference (with an // ampersand). // void PrintHeader(ofstream& outPay) { outPay << "Macro$oft Corporation March Payroll by Bill McQuain" << endl << endl; outPay << " IdNum" << " Gross Pay" << " Ins."; outPay << " F.I.T." << " SSI"; outPay << " Net Pay" << endl; outPay << "============================"; outPay << "================================" << endl; } ///////////////////////////////////////////////////////////////////// // PrintTable is used to print the table of employee data to output // file. // // Input Parameters (passed by value): // // IdNum id numbers of employees // GrossPay gross pay for employees // InsFee insurance fees for employees // FIT income taxes for employees // SSI social security taxes for employees // NetPay net pay for employees // NumEmp number of employees to print data for // // The function doesn't need to return a value, so it's void. // void PrintTable(const int IdNum[], const float GrossPay[], const float InsFee[], const float FIT[], const float SSI[], const float NetPay[],int NumEmp) { ofstream outPay; // output file stream outPay.open("outpay.dat"); // open the output file // Set up for floating point output: outPay.setf(ios::fixed, ios::floatfield); outPay.setf(ios::showpoint); // Print the header for the table: // PrintHeader(outPay); // Print the table, line by line: // for (int count = 0; count < NumEmp; count++) { outPay << setw( 6) << IdNum[count]; outPay << setw(12) << setprecision(2) << GrossPay[count]; outPay << setw(10) << setprecision(2) << InsFee[count]; outPay << setw(10) << setprecision(2) << FIT[count]; outPay << setw(10) << setprecision(2) << SSI[count]; outPay << setw(12) << setprecision(2) << NetPay[count]; outPay << endl; } // Calculate and print averages: // CalcAvgs(outPay, GrossPay, InsFee, FIT, SSI, NetPay, NumEmp); } ///////////////////////////////////////////////////////////////////// // CalcAvgs is used to print final averages to input file. // // Output Parameter (passed by reference): // // outPay output file stream variable // // Input Parameters (passed by value): // // TotalGross total gross pay (for all employees) // TotalIns total insurance fees // TotalFIT total income tax // TotalSSI total social security tax // TotalNet total net pay // NumEmployees total number of employees // // The function doesn't need to return a value, so it's void. // void CalcAvgs(ofstream& outPay, const float GrossPay[], const float InsFee[], const float FIT[], const float SSI[], const float NetPay[], int NumEmp) { float TotalGross = 0.0f, // total of all gross pay TotalNet = 0.0f, // total of all net pay TotalIns = 0.0f, // total of all insurance fees TotalSSI = 0.0f, // total of all SS tax TotalFIT = 0.0f; // total of all income tax // Print out footer for table: outPay << "============================"; outPay << "================================" << endl; // If NumEmp > 0 then calculate totals and print out averages; // otherwise print zeros for the averages. // if (NumEmp) { for (int count = 0; count < NumEmp; count++) { TotalGross += GrossPay[count]; TotalIns += InsFee[count]; TotalFIT += FIT[count]; TotalSSI += SSI[count]; TotalNet += NetPay[count]; } outPay << " Avg:"; outPay << setw(12) << setprecision(2) << TotalGross/NumEmp; outPay << setw(10) << setprecision(2) << TotalIns/NumEmp; outPay << setw(10) << setprecision(2) << TotalFIT/NumEmp; outPay << setw(10) << setprecision(2) << TotalSSI/NumEmp; outPay << setw(12) << setprecision(2) << TotalNet/NumEmp; outPay << endl; } else { outPay << " Avg:"; outPay << setw(12) << setprecision(2) << 0.0f; outPay << setw(10) << setprecision(2) << 0.0f; outPay << setw(10) << setprecision(2) << 0.0f; outPay << setw(10) << setprecision(2) << 0.0f; outPay << setw(12) << setprecision(2) << 0.0f; outPay << endl; } }