//********************************************************
//
// Assignment 7 - Structures and Strings
//
// Name: John Semenuk
//
// Class: C Programming, Spring 2026
//
// Date: 29-Mar-2026
//
// Description: Program calculates overtime, gross pay, state & federal tax,
// net pay, and prints totals, averages, min/max values
// for a group of employees. Uses structures, arrays, and functions.
//
//********************************************************
#include <stdio.h>
#include <string.h>
#include <ctype.h>
//****************************
// Constants
//****************************
#define SIZE 5 // Number of employees
#define STD_HOURS 40.0 // Standard work hours per week
#define OT_RATE 1.5 // Overtime pay multiplier
#define MA_TAX_RATE 0.05 // Massachusetts state tax rate
#define NH_TAX_RATE 0.0 // New Hampshire state tax rate
#define VT_TAX_RATE 0.06 // Vermont state tax rate
#define CA_TAX_RATE 0.07 // California state tax rate
#define DEFAULT_TAX_RATE 0.08 // Default tax rate for all other states
#define FED_TAX_RATE 0.25 // Federal tax rate
#define FIRST_NAME_SIZE 10 // Max length of first name
#define LAST_NAME_SIZE 10 // Max length of last name
#define TAX_STATE_SIZE 3 // Size for 2-character state abbreviation + null
//****************************
// Structures
//****************************
// Stores an employee's first and last name
struct name {
char firstName[FIRST_NAME_SIZE];
char lastName[LAST_NAME_SIZE];
};
// Stores all data related to an employee
struct employee {
struct name empName; // Employee's name
char taxState[TAX_STATE_SIZE]; // Employee's state for tax purposes
long int clockNumber; // Employee clock number
float wageRate; // Hourly wage rate
float hours; // Total hours worked
float overtimeHrs; // Overtime hours worked
float grossPay; // Total gross pay
float stateTax; // Calculated state tax
float fedTax; // Calculated federal tax
float netPay; // Net pay after taxes
};
// Stores totals for all employees
struct totals {
float total_wageRate;
float total_hours;
float total_overtimeHrs;
float total_grossPay;
float total_stateTax;
float total_fedTax;
float total_netPay;
};
// Stores min and max values for employee stats
struct min_max {
float min_wageRate, max_wageRate;
float min_hours, max_hours;
float min_overtimeHrs, max_overtimeHrs;
float min_grossPay, max_grossPay;
float min_stateTax, max_stateTax;
float min_fedTax, max_fedTax;
float min_netPay, max_netPay;
};
//****************************
// Function Prototypes
//****************************
/*
* Function: getHours
* Purpose: Prompt user to enter hours worked for an employee
* Parameters: long int clockNumber - employee's clock number
* Returns: float - number of hours worked
*/
float getHours(long int clockNumber);
/*
* Function: calcOvertimeHrs
* Purpose: Calculate overtime hours based on standard hours
* Parameters: float hours - total hours worked
* Returns: float - number of overtime hours
*/
float calcOvertimeHrs(float hours);
/*
* Function: calcGrossPay
* Purpose: Calculate gross pay including overtime
* Parameters: float wageRate - hourly wage
* float hours - total hours worked
* float overtimeHrs - overtime hours
* Returns: float - total gross pay
*/
float calcGrossPay(float wageRate, float hours, float overtimeHrs);
/*
* Function: calcStateTax
* Purpose: Calculate state tax based on state code
* Parameters: float grossPay - gross pay
* char taxState[] - 2-letter state code
* Returns: float - calculated state tax
*/
float calcStateTax(float grossPay, char taxState[]);
/*
* Function: calcFedTax
* Purpose: Calculate federal tax on gross pay
* Parameters: float grossPay - gross pay
* Returns: float - calculated federal tax
*/
float calcFedTax(float grossPay);
/*
* Function: calcNetPay
* Purpose: Calculate net pay after taxes
* Parameters: float grossPay - gross pay
* float stateTax - state tax
* float fedTax - federal tax
* Returns: float - net pay
*/
float calcNetPay(float grossPay, float stateTax, float fedTax);
/*
* Function: printHeader
* Purpose: Print table header for employee payroll
* Parameters: None
* Returns: void
*/
void printHeader(void);
/*
* Function: printEmp
* Purpose: Print details of one employee
* Parameters: employee data items
* Returns: void
*/
void printEmp(char firstName[], char lastName[], char taxState[], long int clockNumber,
float wageRate, float hours, float overtimeHrs, float grossPay,
float stateTax, float fedTax, float netPay);
/*
* Function: calcEmployeeTotals
* Purpose: Update totals structure with values from one employee
* Parameters: employee data items, struct totals employeeTotals
* Returns: struct totals - updated totals
*/
struct totals calcEmployeeTotals(float wageRate, float hours, float overtimeHrs,
float grossPay, float stateTax, float fedTax,
float netPay, struct totals employeeTotals);
/*
* Function: calcEmployeeMinMax
* Purpose: Update min/max structure with values from one employee
* Parameters: employee data items, struct min_max employeeMinMax, int arrayIndex
* Returns: struct min_max - updated min/max values
*/
struct min_max calcEmployeeMinMax(float wageRate, float hours, float overtimeHrs,
float grossPay, float stateTax, float fedTax,
float netPay, struct min_max employeeMinMax,
int arrayIndex);
/*
* Function: printEmpStatistics
* Purpose: Print totals, averages, min, and max statistics
* Parameters: struct totals employeeTotals, struct min_max employeeMinMax, int theSize
* Returns: void
*/
void printEmpStatistics(struct totals employeeTotals, struct min_max employeeMinMax, int theSize);
//****************************
// Main Program
//****************************
int main() {
int i; // Loop counter
// Initialize employee data
struct employee employeeData[SIZE] = {
{ {"Connie", "Cobol"}, "MA", 98401, 10.60 },
{ {"Mary", "Apl"}, "NH", 526488, 9.75 },
{ {"Frank", "Fortran"}, "VT", 765349, 10.50 },
{ {"Jeff", "Ada"}, "NY", 34645, 12.25 },
{ {"Anton", "Pascal"}, "CA", 127615, 8.35 }
};
struct totals employeeTotals = {0}; // Initialize totals
struct min_max employeeMinMax = {0}; // Initialize min/max values
// Process each employee
for (i = 0; i < SIZE; ++i) {
employeeData[i].hours = getHours(employeeData[i].clockNumber); // Input hours
employeeData[i].overtimeHrs = calcOvertimeHrs(employeeData[i].hours); // Calc OT
employeeData[i].grossPay = calcGrossPay(employeeData[i].wageRate, employeeData[i].hours, employeeData[i].overtimeHrs); // Calc gross
employeeData[i].stateTax = calcStateTax(employeeData[i].grossPay, employeeData[i].taxState); // Calc state tax
employeeData[i].fedTax = calcFedTax(employeeData[i].grossPay); // Calc federal tax
employeeData[i].netPay = calcNetPay(employeeData[i].grossPay, employeeData[i].stateTax, employeeData[i].fedTax); // Calc net pay
// Update totals and min/max
employeeTotals = calcEmployeeTotals(employeeData[i].wageRate, employeeData[i].hours,
employeeData[i].overtimeHrs, employeeData[i].grossPay,
employeeData[i].stateTax, employeeData[i].fedTax,
employeeData[i].netPay, employeeTotals);
employeeMinMax = calcEmployeeMinMax(employeeData[i].wageRate, employeeData[i].hours,
employeeData[i].overtimeHrs, employeeData[i].grossPay,
employeeData[i].stateTax, employeeData[i].fedTax,
employeeData[i].netPay, employeeMinMax, i);
}
// Print results
printHeader();
for (i = 0; i < SIZE; ++i) {
printEmp(employeeData[i].empName.firstName, employeeData[i].empName.lastName,
employeeData[i].taxState, employeeData[i].clockNumber,
employeeData[i].wageRate, employeeData[i].hours,
employeeData[i].overtimeHrs, employeeData[i].grossPay,
employeeData[i].stateTax, employeeData[i].fedTax, employeeData[i].netPay);
}
// Print totals, averages, min/max
printEmpStatistics(employeeTotals, employeeMinMax, SIZE);
return 0;
}
//**************************************************************
// Function Implementations
//**************************************************************
float getHours(long int clockNumber) {
float theHoursWorked; // Stores input hours
printf("\nEnter hours worked by emp # %06li: ", clockNumber
); scanf("%f", &theHoursWorked
); return theHoursWorked;
}
float calcOvertimeHrs(float hours) {
float overtime = (hours > STD_HOURS) ? (hours - STD_HOURS) : 0; // OT calculation
return overtime;
}
float calcGrossPay(float wageRate, float hours, float overtimeHrs) {
float normalPay = wageRate * (hours - overtimeHrs); // Regular pay
float overtimePay = overtimeHrs * (OT_RATE * wageRate); // OT pay
return normalPay + overtimePay; // Total gross pay
}
float calcStateTax(float grossPay, char taxState[]) {
float tax; // Stores calculated state tax
taxState
[0] = toupper(taxState
[0]); taxState
[1] = toupper(taxState
[1]);
// Determine state tax
if (strcmp(taxState
, "MA") == 0) tax
= grossPay
* MA_TAX_RATE
; else if (strcmp(taxState
, "NH") == 0) tax
= grossPay
* NH_TAX_RATE
; else if (strcmp(taxState
, "VT") == 0) tax
= grossPay
* VT_TAX_RATE
; else if (strcmp(taxState
, "CA") == 0) tax
= grossPay
* CA_TAX_RATE
; else tax = grossPay * DEFAULT_TAX_RATE;
return tax;
}
float calcFedTax(float grossPay) {
return grossPay * FED_TAX_RATE; // Federal tax
}
float calcNetPay(float grossPay, float stateTax, float fedTax) {
return grossPay - (stateTax + fedTax); // Net pay after taxes
}
void printHeader(void) {
printf("\n\n*** Pay Calculator ***\n"); printf("\n--------------------------------------------------------------"); printf("-------------------"); printf("\nName Tax Clock# Wage Hours OT Gross "); printf("\n--------------------------------------------------------------"); }
void printEmp(char firstName[], char lastName[], char taxState[], long int clockNumber,
float wageRate, float hours, float overtimeHrs, float grossPay,
float stateTax, float fedTax, float netPay) {
char name[FIRST_NAME_SIZE + LAST_NAME_SIZE + 1]; // Combined full name
printf("\n%-20.20s %-2.2s %06li %5.2f %4.1f %4.1f %7.2f %6.2f %7.2f %8.2f", name, taxState, clockNumber, wageRate, hours, overtimeHrs, grossPay, stateTax, fedTax, netPay);
}
struct totals calcEmployeeTotals(float wageRate, float hours, float overtimeHrs,
float grossPay, float stateTax, float fedTax,
float netPay, struct totals employeeTotals) {
// Add this employee's values to running totals
employeeTotals.total_wageRate += wageRate;
employeeTotals.total_hours += hours;
employeeTotals.total_overtimeHrs += overtimeHrs;
employeeTotals.total_grossPay += grossPay;
employeeTotals.total_stateTax += stateTax;
employeeTotals.total_fedTax += fedTax;
employeeTotals.total_netPay += netPay;
return employeeTotals;
}
struct min_max calcEmployeeMinMax(float wageRate, float hours, float overtimeHrs,
float grossPay, float stateTax, float fedTax,
float netPay, struct min_max employeeMinMax,
int arrayIndex) {
// Initialize min/max with first employee
if (arrayIndex == 0) {
employeeMinMax.min_wageRate = employeeMinMax.max_wageRate = wageRate;
employeeMinMax.min_hours = employeeMinMax.max_hours = hours;
employeeMinMax.min_overtimeHrs = employeeMinMax.max_overtimeHrs = overtimeHrs;
employeeMinMax.min_grossPay = employeeMinMax.max_grossPay = grossPay;
employeeMinMax.min_stateTax = employeeMinMax.max_stateTax = stateTax;
employeeMinMax.min_fedTax = employeeMinMax.max_fedTax = fedTax;
employeeMinMax.min_netPay = employeeMinMax.max_netPay = netPay;
} else {
// Update min/max values for each metric
if (wageRate < employeeMinMax.min_wageRate) employeeMinMax.min_wageRate = wageRate;
if (wageRate > employeeMinMax.max_wageRate) employeeMinMax.max_wageRate = wageRate;
if (hours < employeeMinMax.min_hours) employeeMinMax.min_hours = hours;
if (hours > employeeMinMax.max_hours) employeeMinMax.max_hours = hours;
if (overtimeHrs < employeeMinMax.min_overtimeHrs) employeeMinMax.min_overtimeHrs = overtimeHrs;
if (overtimeHrs > employeeMinMax.max_overtimeHrs) employeeMinMax.max_overtimeHrs = overtimeHrs;
if (grossPay < employeeMinMax.min_grossPay) employeeMinMax.min_grossPay = grossPay;
if (grossPay > employeeMinMax.max_grossPay) employeeMinMax.max_grossPay = grossPay;
if (stateTax < employeeMinMax.min_stateTax) employeeMinMax.min_stateTax = stateTax;
if (stateTax > employeeMinMax.max_stateTax) employeeMinMax.max_stateTax = stateTax;
if (fedTax < employeeMinMax.min_fedTax) employeeMinMax.min_fedTax = fedTax;
if (fedTax > employeeMinMax.max_fedTax) employeeMinMax.max_fedTax = fedTax;
if (netPay < employeeMinMax.min_netPay) employeeMinMax.min_netPay = netPay;
if (netPay > employeeMinMax.max_netPay) employeeMinMax.max_netPay = netPay;
}
return employeeMinMax;
}
void printEmpStatistics(struct totals employeeTotals, struct min_max employeeMinMax, int theSize) {
printf("\n--------------------------------------------------------------"); printf("-------------------");
// Print totals
printf("\nTotals: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f", employeeTotals.total_wageRate, employeeTotals.total_hours, employeeTotals.total_overtimeHrs,
employeeTotals.total_grossPay, employeeTotals.total_stateTax, employeeTotals.total_fedTax,
employeeTotals.total_netPay);
// Print averages
if (theSize > 0)
printf("\nAverages: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f", employeeTotals.total_wageRate/theSize, employeeTotals.total_hours/theSize,
employeeTotals.total_overtimeHrs/theSize, employeeTotals.total_grossPay/theSize,
employeeTotals.total_stateTax/theSize, employeeTotals.total_fedTax/theSize,
employeeTotals.total_netPay/theSize);
// Print min values
printf("\nMinimum: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f", employeeMinMax.min_wageRate, employeeMinMax.min_hours, employeeMinMax.min_overtimeHrs,
employeeMinMax.min_grossPay, employeeMinMax.min_stateTax, employeeMinMax.min_fedTax,
employeeMinMax.min_netPay);
// Print max values
printf("\nMaximum: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f", employeeMinMax.max_wageRate, employeeMinMax.max_hours, employeeMinMax.max_overtimeHrs,
employeeMinMax.max_grossPay, employeeMinMax.max_stateTax, employeeMinMax.max_fedTax,
employeeMinMax.max_netPay);
}