fork download
  1. //********************************************************
  2. //
  3. // Assignment 9 - Linked Lists
  4. //
  5. // Name: John Semenuk
  6. //
  7. // Class: C Programming, Spring 2026
  8. //
  9. // Date: April 9, 2026
  10. //
  11. // Description: Program which determines overtime and
  12. // gross pay for a set of employees with outputs sent
  13. // to standard output (the screen).
  14. //
  15. // This assignment also adds the employee name, their tax state,
  16. // and calculates the state tax, federal tax, and net pay. It
  17. // also calculates totals, averages, minimum, and maximum values.
  18. //
  19. // Array and Structure references have all been replaced with
  20. // pointer references to speed up the processing of this code.
  21. // A linked list has been created and deployed to dynamically
  22. // allocate and process employees as needed.
  23. //
  24. // Call by Reference design (using pointers)
  25. //
  26. //********************************************************
  27.  
  28. // necessary header files
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <ctype.h> // for char functions
  32. #include <stdlib.h> // for malloc
  33.  
  34. // define constants
  35. #define STD_HOURS 40.0
  36. #define OT_RATE 1.5
  37. #define MA_TAX_RATE 0.05
  38. #define NH_TAX_RATE 0.0
  39. #define VT_TAX_RATE 0.06
  40. #define CA_TAX_RATE 0.07
  41. #define DEFAULT_TAX_RATE 0.08
  42. #define NAME_SIZE 20
  43. #define TAX_STATE_SIZE 3
  44. #define FED_TAX_RATE 0.25
  45. #define FIRST_NAME_SIZE 10
  46. #define LAST_NAME_SIZE 10
  47.  
  48. // Define a global structure type to store an employee name
  49. struct name
  50. {
  51. char firstName[FIRST_NAME_SIZE];
  52. char lastName [LAST_NAME_SIZE];
  53. };
  54.  
  55. // Define a global structure type to pass employee data between functions
  56. struct employee
  57. {
  58. struct name empName;
  59. char taxState [TAX_STATE_SIZE];
  60. long int clockNumber;
  61. float wageRate;
  62. float hours;
  63. float overtimeHrs;
  64. float grossPay;
  65. float stateTax;
  66. float fedTax;
  67. float netPay;
  68. struct employee * next;
  69. };
  70.  
  71. // this structure type defines the totals of all floating point items
  72. struct totals
  73. {
  74. float total_wageRate;
  75. float total_hours;
  76. float total_overtimeHrs;
  77. float total_grossPay;
  78. float total_stateTax;
  79. float total_fedTax;
  80. float total_netPay;
  81. };
  82.  
  83. // this structure type defines the min and max values of all floating
  84. struct min_max
  85. {
  86. float min_wageRate;
  87. float min_hours;
  88. float min_overtimeHrs;
  89. float min_grossPay;
  90. float min_stateTax;
  91. float min_fedTax;
  92. float min_netPay;
  93. float max_wageRate;
  94. float max_hours;
  95. float max_overtimeHrs;
  96. float max_grossPay;
  97. float max_stateTax;
  98. float max_fedTax;
  99. float max_netPay;
  100. };
  101.  
  102. // define prototypes here for each function except main
  103. struct employee * getEmpData (void);
  104. int isEmployeeSize (struct employee * head_ptr);
  105. void calcOvertimeHrs (struct employee * head_ptr);
  106. void calcGrossPay (struct employee * head_ptr);
  107. void printHeader (void);
  108. void printEmp (struct employee * head_ptr);
  109. void calcStateTax (struct employee * head_ptr);
  110. void calcFedTax (struct employee * head_ptr);
  111. void calcNetPay (struct employee * head_ptr);
  112. void calcEmployeeTotals (struct employee * head_ptr,
  113. struct totals * emp_totals_ptr);
  114.  
  115. void calcEmployeeMinMax (struct employee * head_ptr,
  116. struct min_max * emp_minMax_ptr);
  117.  
  118. void printEmpStatistics (struct totals * emp_totals_ptr,
  119. struct min_max * emp_minMax_ptr,
  120. int theSize);
  121.  
  122. int main ()
  123. {
  124.  
  125. struct employee * head_ptr; // always points to first linked list node
  126. int theSize; // number of employees processed
  127.  
  128. struct totals employeeTotals = {0,0,0,0,0,0,0};
  129. struct totals * emp_totals_ptr = &employeeTotals;
  130.  
  131. struct min_max employeeMinMax = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  132. struct min_max * emp_minMax_ptr = &employeeMinMax;
  133.  
  134. head_ptr = getEmpData ();
  135.  
  136. theSize = isEmployeeSize (head_ptr);
  137.  
  138. if (theSize <= 0)
  139. {
  140. printf("\n\n**** There was no employee input to process ***\n");
  141. }
  142.  
  143. else
  144. {
  145. calcOvertimeHrs (head_ptr);
  146. calcGrossPay (head_ptr);
  147. calcStateTax (head_ptr);
  148. calcFedTax (head_ptr);
  149. calcNetPay (head_ptr);
  150. calcEmployeeTotals (head_ptr, &employeeTotals);
  151. calcEmployeeMinMax (head_ptr, &employeeMinMax);
  152. printHeader();
  153. printEmp (head_ptr);
  154. printEmpStatistics (&employeeTotals, &employeeMinMax, theSize);
  155. }
  156.  
  157. printf ("\n\n *** End of Program *** \n");
  158. return (0);
  159. }
  160.  
  161. //**************************************************************
  162. // Function: getEmpData
  163. //
  164. // Purpose: Obtains input from user: employee name (first an last),
  165. // tax state, clock number, hourly wage, and hours worked
  166. // in a given week.
  167. //
  168. // Information in stored in a dynamically created linked
  169. // list for all employees.
  170. //
  171. // Parameters: void
  172. //
  173. // Returns:
  174. //
  175. // head_ptr - a pointer to the beginning of the dynamically
  176. // created linked list that contains the initial
  177. // input for each employee.
  178. //
  179. //**************************************************************
  180. struct employee * getEmpData (void)
  181. {
  182. char answer[80]; // user prompt response
  183. int more_data = 1; // a flag to indicate if another employee
  184. // needs to be processed
  185. char value; // the first char of the user prompt response
  186.  
  187. struct employee *current_ptr, *head_ptr; // pointer to current node
  188. head_ptr = (struct employee *) malloc (sizeof(struct employee));
  189. current_ptr = head_ptr;
  190. // process while there is still input
  191. while (more_data)
  192. {
  193.  
  194. // read in employee first and last name
  195. printf ("\nEnter employee first name: ");
  196. scanf ("%s", current_ptr->empName.firstName);
  197. printf ("\nEnter employee last name: ");
  198. scanf ("%s", current_ptr->empName.lastName);
  199. // read in employee tax state
  200. printf ("\nEnter employee two character tax state: ");
  201. scanf ("%s", current_ptr->taxState);
  202. // read in employee clock number
  203. printf("\nEnter employee clock number: ");
  204. scanf("%li", & current_ptr -> clockNumber);
  205. // read in employee wage rate
  206. printf("\nEnter employee hourly wage: ");
  207. scanf("%f", & current_ptr -> wageRate);
  208. // read in employee hours worked
  209. printf("\nEnter hours worked this week: ");
  210. scanf("%f", & current_ptr -> hours);
  211. // ask user if they would like to add another employee
  212. printf("\nWould you like to add another employee? (y/n): ");
  213. scanf("%s", answer);
  214.  
  215. // check first character for a 'Y' for yes
  216. // Ask user if they want to add another employee
  217.  
  218. if ((value = toupper(answer[0])) != 'Y')
  219. {
  220. // no more employees to process
  221. current_ptr->next = (struct employee *) NULL;
  222. more_data = 0;
  223. }
  224. else // Yes, another employee
  225. {
  226. // set the next pointer of the current node to point to the new node
  227. current_ptr->next = (struct employee *) malloc (sizeof(struct employee));
  228. // move the current node pointer to the new node
  229. current_ptr = current_ptr->next;
  230. }
  231. }
  232. return(head_ptr);
  233. }
  234.  
  235. //*************************************************************
  236. // Function: isEmployeeSize
  237. //
  238. // Purpose: Traverses the linked list and keeps a running count
  239. // on how many employees are currently in our list.
  240. //
  241. // Parameters:
  242. //
  243. // head_ptr - pointer to the initial node in our linked list
  244. //
  245. // Returns:
  246. //
  247. // theSize - the number of employees in our linked list
  248. //
  249. //**************************************************************//*************************************************************
  250. int isEmployeeSize (struct employee * head_ptr)
  251. {
  252. struct employee * current_ptr; // pointer to current node
  253. int theSize; // number of link list nodes
  254. // (i.e., employees)
  255.  
  256. theSize = 0; // initialize
  257. // assume there is no data if the first node does
  258. // not have an employee name
  259.  
  260. if (head_ptr->empName.firstName[0] != '\0')
  261. {
  262. // traverse through the linked list, keep a running count of nodes
  263.  
  264. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  265. {
  266. ++theSize; // employee node found, increment
  267. }
  268. }
  269. return (theSize);
  270. }
  271.  
  272. //**************************************************************
  273. // Function: printHeader
  274. //
  275. // Purpose: Prints the initial table header information.
  276. //
  277. // Parameters: none
  278. //
  279. // Returns: void
  280. //
  281. //**************************************************************
  282. void printHeader (void)
  283. {
  284. printf ("\n\n*** Pay Calculator ***\n");
  285. printf("\n--------------------------------------------------------------");
  286. printf("-------------------");
  287. printf("\nName Tax Clock# Wage Hours OT Gross ");
  288. printf(" State Fed Net");
  289. printf("\n State Pay ");
  290. printf(" Tax Tax Pay");
  291. printf("\n--------------------------------------------------------------");
  292. printf("-------------------");
  293. }// printHeader
  294.  
  295. //*************************************************************
  296. // Function: printEmp
  297. //
  298. // Purpose: Prints out all the information for each employee
  299. // in a nice and orderly table format.
  300. //
  301. // Parameters:
  302. //
  303. // head_ptr - pointer to the beginning of our linked list
  304. //
  305. // Returns: void
  306. //
  307. //**************************************************************
  308. void printEmp (struct employee * head_ptr)
  309. {
  310.  
  311.  
  312. // Used to format the employee name
  313. char name [FIRST_NAME_SIZE + LAST_NAME_SIZE + 1];
  314. struct employee * current_ptr; // pointer to current node
  315. // traverse through the linked list to process each employee
  316.  
  317. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  318. {
  319. strcpy (name, current_ptr->empName.firstName);
  320. strcat (name, " ");
  321. strcat (name, current_ptr->empName.lastName);
  322. // Print out current employee in the current linked list node
  323. printf("\n%-20.20s %-2.2s %06li %5.2f %4.1f %4.1f %7.2f %6.2f %7.2f %8.2f",
  324. name, current_ptr->taxState, current_ptr->clockNumber,
  325. current_ptr->wageRate, current_ptr->hours,
  326. current_ptr->overtimeHrs, current_ptr->grossPay,
  327. current_ptr->stateTax, current_ptr->fedTax,
  328. current_ptr->netPay);
  329. }// for
  330. }// printEmp
  331.  
  332. //*************************************************************
  333. // Function: printEmpStatistics
  334. //
  335. // Purpose: Prints out the summary totals and averages of all
  336. // floating point value items for all employees
  337. // that have been processed. It also prints
  338. // out the min and max values.
  339. //
  340. // Parameters:
  341. //
  342. // emp_totals_ptr - pointer to a structure containing a running total
  343. // of all employee floating point items
  344. //
  345. // emp_minMax_ptr - pointer to a structure containing
  346. // the minimum and maximum values of all
  347. // employee floating point items
  348. //
  349. // theSize - the total number of employees processed, used
  350. // to check for zero or negative divide condition.
  351. //
  352. // Returns: void
  353. //
  354. //**************************************************************
  355. void printEmpStatistics (struct totals * emp_totals_ptr,
  356. struct min_max * emp_minMax_ptr,
  357. int theSize)
  358. {
  359. printf("\n--------------------------------------------------------------");
  360. printf("-------------------");
  361.  
  362. printf("\nTotals: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f",
  363. emp_totals_ptr->total_wageRate,
  364. emp_totals_ptr->total_hours,
  365. emp_totals_ptr->total_overtimeHrs,
  366. emp_totals_ptr->total_grossPay,
  367. emp_totals_ptr->total_stateTax,
  368. emp_totals_ptr->total_fedTax,
  369. emp_totals_ptr->total_netPay);
  370.  
  371. if (theSize > 0)
  372. {
  373. printf("\nAverages: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f",
  374. emp_totals_ptr->total_wageRate/theSize,
  375. emp_totals_ptr->total_hours/theSize,
  376. emp_totals_ptr->total_overtimeHrs/theSize,
  377. emp_totals_ptr->total_grossPay/theSize,
  378. emp_totals_ptr->total_stateTax/theSize,
  379. emp_totals_ptr->total_fedTax/theSize,
  380. emp_totals_ptr->total_netPay/theSize);
  381. }
  382.  
  383. printf("\nMinimum: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f",
  384. emp_minMax_ptr->min_wageRate,
  385. emp_minMax_ptr->min_hours,
  386. emp_minMax_ptr->min_overtimeHrs,
  387. emp_minMax_ptr->min_grossPay,
  388. emp_minMax_ptr->min_stateTax,
  389. emp_minMax_ptr->min_fedTax,
  390. emp_minMax_ptr->min_netPay);
  391.  
  392. printf("\nMaximum: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f",
  393. emp_minMax_ptr->max_wageRate,
  394. emp_minMax_ptr->max_hours,
  395. emp_minMax_ptr->max_overtimeHrs,
  396. emp_minMax_ptr->max_grossPay,
  397. emp_minMax_ptr->max_stateTax,
  398. emp_minMax_ptr->max_fedTax,
  399. emp_minMax_ptr->max_netPay);
  400.  
  401.  
  402. // print out the total employees process
  403. printf ("\n\nThe total employees processed was: %i\n", theSize);
  404. }
  405.  
  406. //*************************************************************
  407. // Function: calcOvertimeHrs
  408. //
  409. // Purpose: Calculates the overtime hours worked by an employee
  410. // in a given week for each employee.
  411. //
  412. // Parameters:
  413. //
  414. // head_ptr - pointer to the beginning of our linked list
  415. //
  416. // Returns: void (the overtime hours gets updated by reference)
  417. //
  418. //**************************************************************
  419. void calcOvertimeHrs (struct employee * head_ptr) // pointer to current node
  420. {
  421. struct employee * current_ptr;
  422.  
  423. // traverse through the linked list to calculate overtime hours
  424. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  425. {
  426. // Any overtime ?
  427. if (current_ptr->hours >= STD_HOURS)
  428. current_ptr->overtimeHrs = current_ptr->hours - STD_HOURS;
  429. else // no overtime
  430. current_ptr->overtimeHrs = 0;
  431. } // for
  432.  
  433.  
  434. } // calcOvertimeHrs
  435.  
  436. //*************************************************************
  437. // Function: calcGrossPay
  438. //
  439. // Purpose: Calculates the gross pay based on the the normal pay
  440. // and any overtime pay for a given week for each
  441. // employee.
  442. //
  443. // Parameters:
  444. //
  445. // head_ptr - pointer to the beginning of our linked list
  446. //
  447. // Returns: void (the gross pay gets updated by reference)
  448. //
  449. //**************************************************************
  450.  
  451.  
  452. void calcGrossPay (struct employee * head_ptr)
  453. {
  454. float theNormalPay; // normal pay without any overtime hours
  455. float theOvertimePay; // overtime pay
  456. struct employee * current_ptr; // pointer to current node
  457.  
  458. // traverse through the linked list to calculate gross pay
  459. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  460. {
  461. // calculate normal pay and any overtime pay
  462. theNormalPay = current_ptr->wageRate * (current_ptr->hours - current_ptr->overtimeHrs);
  463. theOvertimePay = current_ptr->overtimeHrs * (OT_RATE * current_ptr->wageRate);
  464.  
  465. // calculate gross pay for employee as normalPay + any overtime pay
  466. current_ptr->grossPay = theNormalPay + theOvertimePay;
  467. }
  468. } // calcGrossPay
  469.  
  470. //*************************************************************
  471. //*************************************************************
  472. // Function: calcStateTax
  473. //
  474. // Purpose: Calculates the State Tax owed based on gross pay
  475. // for each employee. State tax rate is based on the
  476. // the designated tax state based on where the
  477. // employee is actually performing the work. Each
  478. // state decides their tax rate.
  479. //
  480. // Parameters:
  481. //
  482. // head_ptr - pointer to the beginning of our linked list
  483. //
  484. // Returns: void (the state tax gets updated by reference)
  485. //
  486. //**************************************************************
  487.  
  488.  
  489. void calcStateTax (struct employee * head_ptr)
  490. {
  491. struct employee * current_ptr; // pointer to current node
  492.  
  493. // traverse through the linked list to calculate the state tax
  494.  
  495. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  496. {
  497. // Make sure tax state is all uppercase
  498.  
  499. if (islower(current_ptr->taxState[0]))
  500. current_ptr->taxState[0] = toupper(current_ptr->taxState[0]);
  501. if (islower(current_ptr->taxState[1]))
  502. current_ptr->taxState[1] = toupper(current_ptr->taxState[1]);
  503.  
  504. if (strcmp(current_ptr->taxState, "MA") == 0)
  505. current_ptr->stateTax = current_ptr->grossPay * MA_TAX_RATE;
  506. else if (strcmp(current_ptr->taxState, "NH") == 0)
  507. current_ptr->stateTax = current_ptr->grossPay * NH_TAX_RATE;
  508. else if (strcmp(current_ptr->taxState, "VT") == 0)
  509. current_ptr->stateTax = current_ptr->grossPay * VT_TAX_RATE;
  510. else if (strcmp(current_ptr->taxState, "CA") == 0)
  511. current_ptr->stateTax = current_ptr->grossPay * CA_TAX_RATE;
  512. else
  513. current_ptr->stateTax = current_ptr->grossPay * DEFAULT_TAX_RATE;
  514. } // for
  515. }// calcStateTax
  516.  
  517. //*************************************************************
  518. // Function: calcFedTax
  519. //
  520. // Purpose: Calculates the Federal Tax owed based on the gross
  521. // pay for each employee
  522. //
  523. // Parameters:
  524. //
  525. // head_ptr - pointer to the beginning of our linked list
  526. //
  527. // Returns: void (the federal tax gets updated by reference)
  528. //
  529. //**************************************************************
  530.  
  531.  
  532. void calcFedTax (struct employee * head_ptr)
  533. {
  534. struct employee * current_ptr;
  535. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  536. {
  537. current_ptr->fedTax = current_ptr->grossPay * FED_TAX_RATE;
  538. }
  539. }
  540.  
  541. //*************************************************************
  542. void calcNetPay (struct employee * head_ptr)
  543. {
  544. float theTotalTaxes;
  545. struct employee * current_ptr;
  546.  
  547. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  548. {
  549. theTotalTaxes = current_ptr->stateTax + current_ptr->fedTax;
  550. current_ptr->netPay = current_ptr->grossPay - theTotalTaxes;
  551. }
  552. }// calcFedTax
  553.  
  554. //*************************************************************
  555. // Function: calcNetPay
  556. //
  557. // Purpose: Calculates the net pay as the gross pay minus any
  558. // state and federal taxes owed for each employee.
  559. // Essentially, their "take home" pay.
  560. //
  561. // Parameters:
  562. //
  563. // head_ptr - pointer to the beginning of our linked list
  564. //
  565. // Returns: void (the net pay gets updated by reference)
  566. //
  567. //**************************************************************
  568.  
  569.  
  570.  
  571. void calcEmployeeTotals (struct employee * head_ptr,
  572. struct totals * emp_totals_ptr)
  573. {
  574. struct employee * current_ptr;// pointer to current node
  575.  
  576. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  577. {
  578. emp_totals_ptr->total_wageRate += current_ptr->wageRate;
  579. emp_totals_ptr->total_hours += current_ptr->hours;
  580. emp_totals_ptr->total_overtimeHrs += current_ptr->overtimeHrs;
  581. emp_totals_ptr->total_grossPay += current_ptr->grossPay;
  582. emp_totals_ptr->total_stateTax += current_ptr->stateTax;
  583. emp_totals_ptr->total_fedTax += current_ptr->fedTax;
  584. emp_totals_ptr->total_netPay += current_ptr->netPay;
  585. }
  586. }
  587.  
  588. //*************************************************************
  589. void calcEmployeeMinMax (struct employee * head_ptr,
  590. struct min_max * emp_minMax_ptr)
  591. {
  592. struct employee * current_ptr;
  593. current_ptr = head_ptr;
  594.  
  595. emp_minMax_ptr->min_wageRate = current_ptr->wageRate;
  596. emp_minMax_ptr->min_hours = current_ptr->hours;
  597. emp_minMax_ptr->min_overtimeHrs = current_ptr->overtimeHrs;
  598. emp_minMax_ptr->min_grossPay = current_ptr->grossPay;
  599. emp_minMax_ptr->min_stateTax = current_ptr->stateTax;
  600. emp_minMax_ptr->min_fedTax = current_ptr->fedTax;
  601. emp_minMax_ptr->min_netPay = current_ptr->netPay;
  602.  
  603. emp_minMax_ptr->max_wageRate = current_ptr->wageRate;
  604. emp_minMax_ptr->max_hours = current_ptr->hours;
  605. emp_minMax_ptr->max_overtimeHrs = current_ptr->overtimeHrs;
  606. emp_minMax_ptr->max_grossPay = current_ptr->grossPay;
  607. emp_minMax_ptr->max_stateTax = current_ptr->stateTax;
  608. emp_minMax_ptr->max_fedTax = current_ptr->fedTax;
  609. emp_minMax_ptr->max_netPay = current_ptr->netPay;
  610.  
  611. // traverse the linked list
  612. // compare the rest of the employees to each other for min and max
  613.  
  614. current_ptr = current_ptr->next;
  615. // check if current Wage Rate is the new min and/or max
  616. for (; current_ptr; current_ptr = current_ptr->next)
  617. {
  618. if (current_ptr->wageRate < emp_minMax_ptr->min_wageRate)
  619. emp_minMax_ptr->min_wageRate = current_ptr->wageRate;
  620. if (current_ptr->wageRate > emp_minMax_ptr->max_wageRate)
  621. emp_minMax_ptr->max_wageRate = current_ptr->wageRate;
  622. // check if current Hours is the new min and/or max
  623. if (current_ptr->hours < emp_minMax_ptr->min_hours)
  624. emp_minMax_ptr->min_hours = current_ptr->hours;
  625. if (current_ptr->hours > emp_minMax_ptr->max_hours)
  626. emp_minMax_ptr->max_hours = current_ptr->hours;
  627. // check if current Overtime Hours is the new min and/or max
  628. if (current_ptr->overtimeHrs < emp_minMax_ptr->min_overtimeHrs)
  629. emp_minMax_ptr->min_overtimeHrs = current_ptr->overtimeHrs;
  630. if (current_ptr->overtimeHrs > emp_minMax_ptr->max_overtimeHrs)
  631. emp_minMax_ptr->max_overtimeHrs = current_ptr->overtimeHrs;
  632.  
  633. if (current_ptr->grossPay < emp_minMax_ptr->min_grossPay)
  634. emp_minMax_ptr->min_grossPay = current_ptr->grossPay;
  635. if (current_ptr->grossPay > emp_minMax_ptr->max_grossPay)
  636. emp_minMax_ptr->max_grossPay = current_ptr->grossPay;
  637. // check if current Gross Pay is the new min and/or max
  638. if (current_ptr->stateTax < emp_minMax_ptr->min_stateTax)
  639. emp_minMax_ptr->min_stateTax = current_ptr->stateTax;
  640. if (current_ptr->stateTax > emp_minMax_ptr->max_stateTax)
  641. emp_minMax_ptr->max_stateTax = current_ptr->stateTax;
  642. // check if current State Tax is the new min and/or max
  643. if (current_ptr->fedTax < emp_minMax_ptr->min_fedTax)
  644. emp_minMax_ptr->min_fedTax = current_ptr->fedTax;
  645. if (current_ptr->fedTax > emp_minMax_ptr->max_fedTax)
  646. emp_minMax_ptr->max_fedTax = current_ptr->fedTax;
  647. // check if current Net Pay is the new min and/or max
  648. if (current_ptr->netPay < emp_minMax_ptr->min_netPay)
  649. emp_minMax_ptr->min_netPay = current_ptr->netPay;
  650. if (current_ptr->netPay > emp_minMax_ptr->max_netPay)
  651. emp_minMax_ptr->max_netPay = current_ptr->netPay;
  652. } //for
  653. } // calcEmployeeMinMax
Success #stdin #stdout 0s 5308KB
stdin
//********************************************************
//
// Assignment 9 - Linked Lists
//
// Name: John Semenuk
//
// Class: C Programming, Spring 2026
//
// Date: April 9, 2026
//
// Description: Program which determines overtime and 
// gross pay for a set of employees with outputs sent 
// to standard output (the screen).
//
// This assignment also adds the employee name, their tax state,
// and calculates the state tax, federal tax, and net pay.   It
// also calculates totals, averages, minimum, and maximum values.
//
// Array and Structure references have all been replaced with
// pointer references to speed up the processing of this code.
// A linked list has been created and deployed to dynamically
// allocate and process employees as needed.
//
// Call by Reference design (using pointers)
//
//********************************************************

// necessary header files
#include <stdio.h>
#include <string.h>
#include <ctype.h>   // for char functions
#include <stdlib.h>  // for malloc

// define constants
#define STD_HOURS 40.0
#define OT_RATE 1.5
#define MA_TAX_RATE 0.05
#define NH_TAX_RATE 0.0
#define VT_TAX_RATE 0.06
#define CA_TAX_RATE 0.07
#define DEFAULT_TAX_RATE 0.08
#define NAME_SIZE 20
#define TAX_STATE_SIZE 3
#define FED_TAX_RATE 0.25
#define FIRST_NAME_SIZE 10
#define LAST_NAME_SIZE 10

// Define a global structure type to store an employee name
struct name
{
    char firstName[FIRST_NAME_SIZE];
    char lastName [LAST_NAME_SIZE];
};

// Define a global structure type to pass employee data between functions
struct employee
{
    struct name empName;
    char taxState [TAX_STATE_SIZE];
    long int clockNumber;
    float wageRate;
    float hours;
    float overtimeHrs;
    float grossPay;
    float stateTax;
    float fedTax;
    float netPay;
    struct employee * next;
};

// this structure type defines the totals of all floating point items
struct totals
{
    float total_wageRate;
    float total_hours;
    float total_overtimeHrs;
    float total_grossPay;
    float total_stateTax;
    float total_fedTax;
    float total_netPay;
};

// this structure type defines the min and max values of all floating
struct min_max
{
    float min_wageRate;
    float min_hours;
    float min_overtimeHrs;
    float min_grossPay;
    float min_stateTax;
    float min_fedTax;
    float min_netPay;
    float max_wageRate;
    float max_hours;
    float max_overtimeHrs;
    float max_grossPay;
    float max_stateTax;
    float max_fedTax;
    float max_netPay;
};

// define prototypes here for each function except main
struct employee * getEmpData (void);
int isEmployeeSize (struct employee * head_ptr);
void calcOvertimeHrs (struct employee * head_ptr);
void calcGrossPay (struct employee * head_ptr);
void printHeader (void);
void printEmp (struct employee * head_ptr);
void calcStateTax (struct employee * head_ptr);
void calcFedTax (struct employee * head_ptr);
void calcNetPay (struct employee * head_ptr);
void calcEmployeeTotals (struct employee * head_ptr,
                         struct totals * emp_totals_ptr);
                                 
void calcEmployeeMinMax (struct employee * head_ptr,
                         struct min_max * emp_minMax_ptr);
                                  
void printEmpStatistics (struct totals * emp_totals_ptr, 
                         struct min_max * emp_minMax_ptr,
                         int theSize);

int main ()
{

    struct employee * head_ptr; // always points to first linked list node
    int theSize; // number of employees processed
    
    struct totals employeeTotals  = {0,0,0,0,0,0,0};
    struct totals * emp_totals_ptr = &employeeTotals;
    
    struct min_max employeeMinMax = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    struct min_max * emp_minMax_ptr = &employeeMinMax;

    head_ptr = getEmpData ();

    theSize = isEmployeeSize (head_ptr);
    
    if (theSize <= 0)
    {
        printf("\n\n**** There was no employee input to process ***\n");
    }
    
    else
    {    
        calcOvertimeHrs (head_ptr);
        calcGrossPay (head_ptr); 
        calcStateTax (head_ptr);
        calcFedTax (head_ptr);
        calcNetPay (head_ptr); 
        calcEmployeeTotals (head_ptr, &employeeTotals);
        calcEmployeeMinMax (head_ptr, &employeeMinMax);
        printHeader();
        printEmp (head_ptr); 
        printEmpStatistics (&employeeTotals, &employeeMinMax, theSize);
    }
    
    printf ("\n\n *** End of Program *** \n");
    return (0);
}

//**************************************************************
// Function: getEmpData 
// 
// Purpose: Obtains input from user: employee name (first an last), 
//          tax state, clock number, hourly wage, and hours worked
//          in a given week.
//
//          Information in stored in a dynamically created linked
//          list for all employees.
//          
// Parameters: void
// 
// Returns:
//
//    head_ptr - a pointer to the beginning of the dynamically
//               created linked list that contains the initial
//               input for each employee.
//  
//**************************************************************
struct employee * getEmpData (void)
{
    char answer[80];   // user prompt response  
    int more_data = 1; // a flag to indicate if another employee
                      // needs to be processed
    char value;       // the first char of the user prompt response  

    struct employee *current_ptr, *head_ptr; // pointer to current node
    head_ptr = (struct employee *) malloc (sizeof(struct employee));
    current_ptr = head_ptr;
  // process while there is still input
    while (more_data)
    {
        
        // read in employee first and last name
        printf ("\nEnter employee first name: ");
        scanf ("%s", current_ptr->empName.firstName);
        printf ("\nEnter employee last name: ");
        scanf ("%s", current_ptr->empName.lastName);
        // read in employee tax state
        printf ("\nEnter employee two character tax state: ");
        scanf ("%s", current_ptr->taxState);
        // read in employee clock number
        printf("\nEnter employee clock number: ");
        scanf("%li", & current_ptr -> clockNumber);
        // read in employee wage rate
        printf("\nEnter employee hourly wage: ");
        scanf("%f", & current_ptr -> wageRate);
        // read in employee hours worked
        printf("\nEnter hours worked this week: ");
        scanf("%f", & current_ptr -> hours);
        // ask user if they would like to add another employee
        printf("\nWould you like to add another employee? (y/n): ");
        scanf("%s", answer);
        
        // check first character for a 'Y' for yes
        // Ask user if they want to add another employee
 
        if ((value = toupper(answer[0])) != 'Y')
        {
           // no more employees to process
           current_ptr->next = (struct employee *) NULL;
           more_data = 0; 
        }
        else // Yes, another employee
        {
           // set the next pointer of the current node to point to the new node
           current_ptr->next = (struct employee *) malloc (sizeof(struct employee));
            // move the current node pointer to the new node
           current_ptr = current_ptr->next;
        }
    }
    return(head_ptr);
}

//*************************************************************
// Function: isEmployeeSize
//
// Purpose: Traverses the linked list and keeps a running count
//          on how many employees are currently in our list. 
//
// Parameters:
//
//   head_ptr - pointer to the initial node in our linked list
//
// Returns:
//
//   theSize - the number of employees in our linked list
//
//**************************************************************//*************************************************************
int isEmployeeSize (struct employee * head_ptr)
{
    struct employee * current_ptr; // pointer to current node
    int theSize;                   // number of link list nodes
                                   // (i.e., employees)
    
    theSize = 0; // initialize
    // assume there is no data if the first node does
    // not have an employee name
    
    if (head_ptr->empName.firstName[0] != '\0')
    {
        // traverse through the linked list, keep a running count of nodes
        
        for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
        {  
            ++theSize;   // employee node found, increment
        }
    }
    return (theSize);
}

//**************************************************************
// Function: printHeader
// 
// Purpose: Prints the initial table header information.
// 
// Parameters: none
// 
// Returns: void
//  
//**************************************************************
void printHeader (void) 
{ 
    printf ("\n\n*** Pay Calculator ***\n");
    printf("\n--------------------------------------------------------------");
    printf("-------------------");
    printf("\nName                Tax  Clock# Wage   Hours  OT   Gross ");
    printf("  State  Fed      Net");
    printf("\n                   State                           Pay   ");
    printf("  Tax    Tax      Pay");
    printf("\n--------------------------------------------------------------");
    printf("-------------------");
}// printHeader

//************************************************************* 
// Function: printEmp 
// 
// Purpose: Prints out all the information for each employee
//          in a nice and orderly table format.
// 
// Parameters: 
//
//   head_ptr - pointer to the beginning of our linked list
// 
// Returns: void
//  
//**************************************************************
void printEmp (struct employee * head_ptr)
{
    
    
     // Used to format the employee name
    char name [FIRST_NAME_SIZE + LAST_NAME_SIZE + 1];
    struct employee * current_ptr;  // pointer to current node
     // traverse through the linked list to process each employee
    
    for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
    {
        strcpy (name, current_ptr->empName.firstName);
        strcat (name, " "); 
        strcat (name, current_ptr->empName.lastName);
        // Print out current employee in the current linked list node
        printf("\n%-20.20s %-2.2s  %06li %5.2f  %4.1f  %4.1f %7.2f %6.2f %7.2f %8.2f",
               name, current_ptr->taxState, current_ptr->clockNumber, 
               current_ptr->wageRate, current_ptr->hours,
               current_ptr->overtimeHrs, current_ptr->grossPay, 
               current_ptr->stateTax, current_ptr->fedTax, 
               current_ptr->netPay);
    }// for
}// printEmp

//************************************************************* 
// Function: printEmpStatistics 
// 
// Purpose: Prints out the summary totals and averages of all 
//          floating point value items for all employees
//          that have been processed.  It also prints
//          out the min and max values.
// 
// Parameters: 
//
//   emp_totals_ptr - pointer to a structure containing a running total 
//                    of all employee floating point items
//
//   emp_minMax_ptr - pointer to a structure containing
//                    the minimum and maximum values of all
//                    employee floating point items
//
//   theSize - the total number of employees processed, used 
//             to check for zero or negative divide condition.
// 
// Returns: void
//  
//**************************************************************
void printEmpStatistics (struct totals   * emp_totals_ptr,
                         struct min_max  * emp_minMax_ptr,
                         int theSize)
{
    printf("\n--------------------------------------------------------------");
    printf("-------------------");
    
    printf("\nTotals:                         %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f",
           emp_totals_ptr->total_wageRate,
           emp_totals_ptr->total_hours,
           emp_totals_ptr->total_overtimeHrs,
           emp_totals_ptr->total_grossPay,
           emp_totals_ptr->total_stateTax,
           emp_totals_ptr->total_fedTax,
           emp_totals_ptr->total_netPay);
    
    if (theSize > 0)       
    {
        printf("\nAverages:                       %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f",
               emp_totals_ptr->total_wageRate/theSize,
               emp_totals_ptr->total_hours/theSize,
               emp_totals_ptr->total_overtimeHrs/theSize,
               emp_totals_ptr->total_grossPay/theSize,
               emp_totals_ptr->total_stateTax/theSize,
               emp_totals_ptr->total_fedTax/theSize,
               emp_totals_ptr->total_netPay/theSize);
    }
    
    printf("\nMinimum:                        %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f",
           emp_minMax_ptr->min_wageRate,
           emp_minMax_ptr->min_hours,
           emp_minMax_ptr->min_overtimeHrs,
           emp_minMax_ptr->min_grossPay,
           emp_minMax_ptr->min_stateTax,
           emp_minMax_ptr->min_fedTax,
           emp_minMax_ptr->min_netPay);
    
    printf("\nMaximum:                        %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f",
           emp_minMax_ptr->max_wageRate,
           emp_minMax_ptr->max_hours,
           emp_minMax_ptr->max_overtimeHrs,
           emp_minMax_ptr->max_grossPay,
           emp_minMax_ptr->max_stateTax,
           emp_minMax_ptr->max_fedTax,
           emp_minMax_ptr->max_netPay);
     
     
     // print out the total employees process      
    printf ("\n\nThe total employees processed was: %i\n", theSize);
}  

//*************************************************************
// Function: calcOvertimeHrs
//
// Purpose: Calculates the overtime hours worked by an employee
//          in a given week for each employee.
//
// Parameters:
//
//   head_ptr - pointer to the beginning of our linked list
//
// Returns: void (the overtime hours gets updated by reference)
//
//**************************************************************
void calcOvertimeHrs (struct employee * head_ptr) // pointer to current node
{
    struct employee * current_ptr;
    
     // traverse through the linked list to calculate overtime hours
    for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
    {  
         // Any overtime ?
        if (current_ptr->hours >= STD_HOURS)
            current_ptr->overtimeHrs = current_ptr->hours - STD_HOURS;
        else // no overtime
            current_ptr->overtimeHrs = 0;
    } // for

	
} // calcOvertimeHrs

//*************************************************************
// Function: calcGrossPay
//
// Purpose: Calculates the gross pay based on the the normal pay
//          and any overtime pay for a given week for each
//          employee.
//
// Parameters:
//
//   head_ptr - pointer to the beginning of our linked list
//
// Returns: void (the gross pay gets updated by reference)
//
//**************************************************************


void calcGrossPay (struct employee * head_ptr)
{
    float theNormalPay;  // normal pay without any overtime hours
    float theOvertimePay; // overtime pay
    struct employee * current_ptr; // pointer to current node
    
    // traverse through the linked list to calculate gross pay
    for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
    {
          // calculate normal pay and any overtime pay
        theNormalPay = current_ptr->wageRate * (current_ptr->hours - current_ptr->overtimeHrs);
        theOvertimePay = current_ptr->overtimeHrs * (OT_RATE * current_ptr->wageRate);
        
         // calculate gross pay for employee as normalPay + any overtime pay
        current_ptr->grossPay = theNormalPay + theOvertimePay;
    }
}  // calcGrossPay

//*************************************************************
//*************************************************************
// Function: calcStateTax
//
// Purpose: Calculates the State Tax owed based on gross pay
//          for each employee.  State tax rate is based on the 
//          the designated tax state based on where the
//          employee is actually performing the work.  Each
//          state decides their tax rate.
//
// Parameters:
//
//   head_ptr - pointer to the beginning of our linked list
//
// Returns: void (the state tax gets updated by reference)
//
//**************************************************************
 

void calcStateTax (struct employee * head_ptr)
{
    struct employee * current_ptr; // pointer to current node
    
     // traverse through the linked list to calculate the state tax

    for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
    {
         // Make sure tax state is all uppercase
        
        if (islower(current_ptr->taxState[0]))
            current_ptr->taxState[0] = toupper(current_ptr->taxState[0]);
        if (islower(current_ptr->taxState[1]))
            current_ptr->taxState[1] = toupper(current_ptr->taxState[1]);
       
        if (strcmp(current_ptr->taxState, "MA") == 0)
            current_ptr->stateTax = current_ptr->grossPay * MA_TAX_RATE;
        else if (strcmp(current_ptr->taxState, "NH") == 0)
            current_ptr->stateTax = current_ptr->grossPay * NH_TAX_RATE;
        else if (strcmp(current_ptr->taxState, "VT") == 0)
            current_ptr->stateTax = current_ptr->grossPay * VT_TAX_RATE;
        else if (strcmp(current_ptr->taxState, "CA") == 0)
            current_ptr->stateTax = current_ptr->grossPay * CA_TAX_RATE;
        else
            current_ptr->stateTax = current_ptr->grossPay * DEFAULT_TAX_RATE;
    } // for
}// calcStateTax

//*************************************************************
// Function: calcFedTax
//
// Purpose: Calculates the Federal Tax owed based on the gross 
//          pay for each employee
//
// Parameters:
//
//   head_ptr - pointer to the beginning of our linked list
//
// Returns: void (the federal tax gets updated by reference)
//
//**************************************************************


void calcFedTax (struct employee * head_ptr)
{
    struct employee * current_ptr;
    for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
    {
        current_ptr->fedTax = current_ptr->grossPay * FED_TAX_RATE;
    }
}

//*************************************************************
void calcNetPay (struct employee * head_ptr)
{
    float theTotalTaxes;
    struct employee * current_ptr;

    for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
    {
        theTotalTaxes = current_ptr->stateTax + current_ptr->fedTax;
        current_ptr->netPay = current_ptr->grossPay - theTotalTaxes;
    }
}// calcFedTax

//*************************************************************
// Function: calcNetPay
//
// Purpose: Calculates the net pay as the gross pay minus any
//          state and federal taxes owed for each employee.
//          Essentially, their "take home" pay.
//
// Parameters:
//
//   head_ptr - pointer to the beginning of our linked list
//
// Returns: void (the net pay gets updated by reference)
//
//**************************************************************



void calcEmployeeTotals (struct employee * head_ptr,
                         struct totals * emp_totals_ptr)
{
    struct employee * current_ptr;// pointer to current node

    for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
    {
        emp_totals_ptr->total_wageRate += current_ptr->wageRate;
        emp_totals_ptr->total_hours += current_ptr->hours;
        emp_totals_ptr->total_overtimeHrs += current_ptr->overtimeHrs;
        emp_totals_ptr->total_grossPay += current_ptr->grossPay;
        emp_totals_ptr->total_stateTax += current_ptr->stateTax;
        emp_totals_ptr->total_fedTax += current_ptr->fedTax;
        emp_totals_ptr->total_netPay += current_ptr->netPay;
    }
}

//*************************************************************
void calcEmployeeMinMax (struct employee * head_ptr,
                         struct min_max * emp_minMax_ptr)
{
    struct employee * current_ptr;
    current_ptr = head_ptr;

    emp_minMax_ptr->min_wageRate = current_ptr->wageRate; 
    emp_minMax_ptr->min_hours = current_ptr->hours;
    emp_minMax_ptr->min_overtimeHrs = current_ptr->overtimeHrs; 
    emp_minMax_ptr->min_grossPay = current_ptr->grossPay;
    emp_minMax_ptr->min_stateTax = current_ptr->stateTax;
    emp_minMax_ptr->min_fedTax = current_ptr->fedTax;
    emp_minMax_ptr->min_netPay = current_ptr->netPay;
        
    emp_minMax_ptr->max_wageRate = current_ptr->wageRate; 
    emp_minMax_ptr->max_hours = current_ptr->hours;
    emp_minMax_ptr->max_overtimeHrs = current_ptr->overtimeHrs;
    emp_minMax_ptr->max_grossPay = current_ptr->grossPay;
    emp_minMax_ptr->max_stateTax = current_ptr->stateTax;
    emp_minMax_ptr->max_fedTax = current_ptr->fedTax;
    emp_minMax_ptr->max_netPay = current_ptr->netPay;

    // traverse the linked list
    // compare the rest of the employees to each other for min and max
    
    current_ptr = current_ptr->next;
    // check if current Wage Rate is the new min and/or max
    for (; current_ptr; current_ptr = current_ptr->next) 
    {
        if (current_ptr->wageRate < emp_minMax_ptr->min_wageRate)
            emp_minMax_ptr->min_wageRate = current_ptr->wageRate;
        if (current_ptr->wageRate > emp_minMax_ptr->max_wageRate)
            emp_minMax_ptr->max_wageRate = current_ptr->wageRate;
         // check if current Hours is the new min and/or max
        if (current_ptr->hours < emp_minMax_ptr->min_hours)
            emp_minMax_ptr->min_hours = current_ptr->hours;
        if (current_ptr->hours > emp_minMax_ptr->max_hours)
            emp_minMax_ptr->max_hours = current_ptr->hours;
         // check if current Overtime Hours is the new min and/or max
        if (current_ptr->overtimeHrs < emp_minMax_ptr->min_overtimeHrs)
            emp_minMax_ptr->min_overtimeHrs = current_ptr->overtimeHrs;
        if (current_ptr->overtimeHrs > emp_minMax_ptr->max_overtimeHrs)
            emp_minMax_ptr->max_overtimeHrs = current_ptr->overtimeHrs;
        
        if (current_ptr->grossPay < emp_minMax_ptr->min_grossPay)
            emp_minMax_ptr->min_grossPay = current_ptr->grossPay;
        if (current_ptr->grossPay > emp_minMax_ptr->max_grossPay)
            emp_minMax_ptr->max_grossPay = current_ptr->grossPay;
        // check if current Gross Pay is the new min and/or max
        if (current_ptr->stateTax < emp_minMax_ptr->min_stateTax)
            emp_minMax_ptr->min_stateTax = current_ptr->stateTax;
        if (current_ptr->stateTax > emp_minMax_ptr->max_stateTax)
            emp_minMax_ptr->max_stateTax = current_ptr->stateTax;
         // check if current State Tax is the new min and/or max
        if (current_ptr->fedTax < emp_minMax_ptr->min_fedTax)
            emp_minMax_ptr->min_fedTax = current_ptr->fedTax;
        if (current_ptr->fedTax > emp_minMax_ptr->max_fedTax)
            emp_minMax_ptr->max_fedTax = current_ptr->fedTax;
         // check if current Net Pay is the new min and/or max
        if (current_ptr->netPay < emp_minMax_ptr->min_netPay)
            emp_minMax_ptr->min_netPay = current_ptr->netPay;
        if (current_ptr->netPay > emp_minMax_ptr->max_netPay)
            emp_minMax_ptr->max_netPay = current_ptr->netPay;
    } //for
} // calcEmployeeMinMax
stdout
Enter employee first name: 
Enter employee last name: 
Enter employee two character tax state: 
Enter employee clock number: 
Enter employee hourly wage: 
Enter hours worked this week: 
Would you like to add another employee? (y/n): 

*** Pay Calculator ***

---------------------------------------------------------------------------------
Name                Tax  Clock# Wage   Hours  OT   Gross   State  Fed      Net
                   State                           Pay     Tax    Tax      Pay
---------------------------------------------------------------------------------
//********// //      //  3038287259199220266  0.00   0.0   0.0    0.00   0.00    0.00     0.00
---------------------------------------------------------------------------------
Totals:                          0.00   0.0   0.0    0.00   0.00    0.00     0.00
Averages:                        0.00   0.0   0.0    0.00   0.00    0.00     0.00
Minimum:                         0.00   0.0   0.0    0.00   0.00    0.00     0.00
Maximum:                         0.00   0.0   0.0    0.00   0.00    0.00     0.00

The total employees processed was: 1


 *** End of Program ***