fork(1) download
  1. //********************************************************
  2. //
  3. // Assignment 10 - Linked Lists, Typedef, and Macros
  4. //
  5. // Name: <Isaac M Boahndao>
  6. //
  7. // Class: C Programming, <Spring Semester and 2025>
  8. //
  9. // Date: <04_19_25>
  10. //
  11.  
  12. // Description: Program which determines overtime and
  13. // gross pay for a set of employees with outputs sent
  14. // to standard output (the screen).
  15. //
  16. // This assignment also adds the employee name, their tax state,
  17. // and calculates the state tax, federal tax, and net pay. It
  18. // also calculates totals, averages, minimum, and maximum values.
  19. //
  20. // Array and Structure references have all been replaced with
  21. // pointer references to speed up the processing of this code.
  22. // A linked list has been created and deployed to dynamically
  23. // allocate and process employees as needed.
  24. //
  25. // It will also take advantage of the C Preprocessor features,
  26. // in particular with using macros, and will replace all
  27. // struct type references in the code with a typedef alias
  28. // reference.
  29. //
  30. // Call by Reference design (using pointers)
  31. //
  32. //********************************************************
  33.  
  34. // necessary header files
  35. #include <stdio.h>
  36. #include <string.h>
  37. #include <ctype.h> // for char functions
  38. #include <stdlib.h> // for malloc
  39.  
  40. // define constants
  41. #define STD_HOURS 40.0
  42. #define OT_RATE 1.5
  43. #define MA_TAX_RATE 0.05
  44. #define NH_TAX_RATE 0.0
  45. #define VT_TAX_RATE 0.06
  46. #define CA_TAX_RATE 0.07
  47. #define DEFAULT_STATE_TAX_RATE 0.08
  48. #define NAME_SIZE 20
  49. #define TAX_STATE_SIZE 3
  50. #define FED_TAX_RATE 0.25
  51. #define FIRST_NAME_SIZE 10
  52. #define LAST_NAME_SIZE 10
  53.  
  54. // define macros
  55. #define CALC_OT_HOURS(theHours) ((theHours > STD_HOURS) ? theHours - STD_HOURS : 0)
  56. #define CALC_STATE_TAX(thePay,theStateTaxRate) (thePay * theStateTaxRate)
  57. #define CALC_FED_TAX(thePay) (thePay * FED_TAX_RATE)
  58. #define CALC_NET_PAY(thePay,theStateTax,theFedTax) (thePay - (theStateTax + theFedTax))
  59. #define CALC_NORMAL_PAY(theWageRate,theHours,theOvertimeHrs) \
  60. (theWageRate * (theHours - theOvertimeHrs))
  61. #define CALC_OT_PAY(theWageRate,theOvertimeHrs) (theOvertimeHrs * (OT_RATE * theWageRate))
  62. #define CALC_MIN(theValue, currentMin) ((theValue < currentMin) ? theValue : currentMin)
  63. #define CALC_MAX(theValue, currentMax) ((theValue > currentMax) ? theValue : currentMax)
  64.  
  65. // Define a global structure type to store an employee name
  66. struct name
  67. {
  68. char firstName[FIRST_NAME_SIZE];
  69. char lastName [LAST_NAME_SIZE];
  70. };
  71.  
  72. // Define a global structure type to pass employee data between functions
  73. typedef struct employee
  74. {
  75. struct name empName;
  76. char taxState [TAX_STATE_SIZE];
  77. long int clockNumber;
  78. float wageRate;
  79. float hours;
  80. float overtimeHrs;
  81. float grossPay;
  82. float stateTax;
  83. float fedTax;
  84. float netPay;
  85. struct employee * next;
  86. } EMPLOYEE;
  87.  
  88. // This structure type defines the totals of all floating point items
  89. typedef struct totals
  90. {
  91. float total_wageRate;
  92. float total_hours;
  93. float total_overtimeHrs;
  94. float total_grossPay;
  95. float total_stateTax;
  96. float total_fedTax;
  97. float total_netPay;
  98. } TOTALS;
  99.  
  100. // This structure type defines the min and max values
  101. typedef struct min_max
  102. {
  103. float min_wageRate;
  104. float min_hours;
  105. float min_overtimeHrs;
  106. float min_grossPay;
  107. float min_stateTax;
  108. float min_fedTax;
  109. float min_netPay;
  110. float max_wageRate;
  111. float max_hours;
  112. float max_overtimeHrs;
  113. float max_grossPay;
  114. float max_stateTax;
  115. float max_fedTax;
  116. float max_netPay;
  117. } MIN_MAX;
  118.  
  119. // Function prototypes
  120. EMPLOYEE * getEmpData (void);
  121. int isEmployeeSize (EMPLOYEE * head_ptr);
  122. void calcOvertimeHrs (EMPLOYEE * head_ptr);
  123. void calcGrossPay (EMPLOYEE * head_ptr);
  124. void printHeader (void);
  125. void printEmp (EMPLOYEE * head_ptr);
  126. void calcStateTax (EMPLOYEE * head_ptr);
  127. void calcFedTax (EMPLOYEE * head_ptr);
  128. void calcNetPay (EMPLOYEE * head_ptr);
  129. void calcEmployeeTotals (EMPLOYEE * head_ptr, TOTALS * emp_totals_ptr);
  130. void calcEmployeeMinMax (EMPLOYEE * head_ptr, MIN_MAX * emp_minMax_ptr);
  131. void printEmpStatistics (TOTALS * emp_totals_ptr, MIN_MAX * emp_minMax_ptr, int size);
  132.  
  133. int main ()
  134. {
  135. // Set up head pointer to point to the start of the linked list
  136. EMPLOYEE * head_ptr; // always points to first linked list node
  137. int theSize; // number of employees processed
  138.  
  139. // set up structure to store totals and initialize all to zero
  140. TOTALS employeeTotals = {0,0,0,0,0,0,0};
  141. TOTALS * emp_totals_ptr = &employeeTotals;
  142.  
  143. // set up structure to store min and max values and initialize all to zero
  144. MIN_MAX employeeMinMax = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  145. MIN_MAX * emp_minMax_ptr = &employeeMinMax;
  146.  
  147. // Read the employee input and dynamically allocate linked list
  148. head_ptr = getEmpData ();
  149.  
  150. // determine how many employees are in our linked list
  151. theSize = isEmployeeSize (head_ptr);
  152.  
  153. if (theSize <= 0)
  154. {
  155. printf("\n\n**** There was no employee input to process ***\n");
  156. }
  157. else
  158. {
  159. // Perform calculations
  160. calcOvertimeHrs (head_ptr);
  161. calcGrossPay (head_ptr);
  162. calcStateTax (head_ptr);
  163. calcFedTax (head_ptr);
  164. calcNetPay (head_ptr);
  165.  
  166. // Calculate totals and min/max values
  167. calcEmployeeTotals (head_ptr, &employeeTotals);
  168. calcEmployeeMinMax (head_ptr, &employeeMinMax);
  169.  
  170. // Print results
  171. printHeader();
  172. printEmp (head_ptr);
  173. printEmpStatistics (&employeeTotals, &employeeMinMax, theSize);
  174. }
  175.  
  176. printf ("\n\n *** End of Program *** \n");
  177. return (0);
  178. }
  179.  
  180. // Function implementations...
  181.  
  182. EMPLOYEE * getEmpData (void)
  183. {
  184. char answer[80];
  185. int more_data = 1;
  186. char value;
  187.  
  188. EMPLOYEE *current_ptr, *head_ptr;
  189.  
  190. head_ptr = (EMPLOYEE *) malloc (sizeof(EMPLOYEE));
  191. current_ptr = head_ptr;
  192.  
  193. while (more_data)
  194. {
  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. printf ("\nEnter employee two character tax state: ");
  200. scanf ("%s", current_ptr->taxState);
  201. printf("\nEnter employee clock number: ");
  202. scanf("%li", & current_ptr -> clockNumber);
  203. printf("\nEnter employee hourly wage: ");
  204. scanf("%f", & current_ptr -> wageRate);
  205. printf("\nEnter hours worked this week: ");
  206. scanf("%f", & current_ptr -> hours);
  207.  
  208. printf("\nWould you like to add another employee? (y/n): ");
  209. scanf("%s", answer);
  210.  
  211. if ((value = toupper(answer[0])) != 'Y')
  212. {
  213. current_ptr->next = (EMPLOYEE *) NULL;
  214. more_data = 0;
  215. }
  216. else
  217. {
  218. current_ptr->next = (EMPLOYEE *) malloc (sizeof(EMPLOYEE));
  219. current_ptr = current_ptr->next;
  220. }
  221. }
  222. return(head_ptr);
  223. }
  224.  
  225. int isEmployeeSize (EMPLOYEE * head_ptr)
  226. {
  227. EMPLOYEE * current_ptr;
  228. int theSize = 0;
  229.  
  230. if (head_ptr->empName.firstName[0] != '\0')
  231. {
  232. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  233. {
  234. ++theSize;
  235. }
  236. }
  237. return (theSize);
  238. }
  239.  
  240. void printHeader (void)
  241. {
  242. printf ("\n\n*** Pay Calculator ***\n");
  243. printf("\n--------------------------------------------------------------");
  244. printf("-------------------");
  245. printf("\nName Tax Clock# Wage Hours OT Gross ");
  246. printf(" State Fed Net");
  247. printf("\n State Pay ");
  248. printf(" Tax Tax Pay");
  249. printf("\n--------------------------------------------------------------");
  250. printf("-------------------");
  251. }
  252.  
  253. void printEmp (EMPLOYEE * head_ptr)
  254. {
  255. char name[FIRST_NAME_SIZE + LAST_NAME_SIZE + 1];
  256. EMPLOYEE * current_ptr;
  257.  
  258. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  259. {
  260. strcpy (name, current_ptr->empName.firstName);
  261. strcat (name, " ");
  262. strcat (name, current_ptr->empName.lastName);
  263.  
  264. printf("\n%-20.20s %-2.2s %06li %5.2f %4.1f %4.1f %7.2f %6.2f %7.2f %8.2f",
  265. name, current_ptr->taxState, current_ptr->clockNumber,
  266. current_ptr->wageRate, current_ptr->hours,
  267. current_ptr->overtimeHrs, current_ptr->grossPay,
  268. current_ptr->stateTax, current_ptr->fedTax,
  269. current_ptr->netPay);
  270. }
  271. }
  272.  
  273. void printEmpStatistics (TOTALS * emp_totals_ptr, MIN_MAX * emp_minMax_ptr, int theSize)
  274. {
  275. printf("\n--------------------------------------------------------------");
  276. printf("-------------------");
  277.  
  278. printf("\nTotals: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f",
  279. emp_totals_ptr->total_wageRate,
  280. emp_totals_ptr->total_hours,
  281. emp_totals_ptr->total_overtimeHrs,
  282. emp_totals_ptr->total_grossPay,
  283. emp_totals_ptr->total_stateTax,
  284. emp_totals_ptr->total_fedTax,
  285. emp_totals_ptr->total_netPay);
  286.  
  287. if (theSize > 0)
  288. {
  289. printf("\nAverages: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f",
  290. emp_totals_ptr->total_wageRate/theSize,
  291. emp_totals_ptr->total_hours/theSize,
  292. emp_totals_ptr->total_overtimeHrs/theSize,
  293. emp_totals_ptr->total_grossPay/theSize,
  294. emp_totals_ptr->total_stateTax/theSize,
  295. emp_totals_ptr->total_fedTax/theSize,
  296. emp_totals_ptr->total_netPay/theSize);
  297. }
  298.  
  299. printf("\nMinimum: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f",
  300. emp_minMax_ptr->min_wageRate,
  301. emp_minMax_ptr->min_hours,
  302. emp_minMax_ptr->min_overtimeHrs,
  303. emp_minMax_ptr->min_grossPay,
  304. emp_minMax_ptr->min_stateTax,
  305. emp_minMax_ptr->min_fedTax,
  306. emp_minMax_ptr->min_netPay);
  307.  
  308. printf("\nMaximum: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f",
  309. emp_minMax_ptr->max_wageRate,
  310. emp_minMax_ptr->max_hours,
  311. emp_minMax_ptr->max_overtimeHrs,
  312. emp_minMax_ptr->max_grossPay,
  313. emp_minMax_ptr->max_stateTax,
  314. emp_minMax_ptr->max_fedTax,
  315. emp_minMax_ptr->max_netPay);
  316.  
  317. printf ("\n\nThe total employees processed was: %i\n", theSize);
  318. }
  319.  
  320. void calcOvertimeHrs (EMPLOYEE * head_ptr)
  321. {
  322. EMPLOYEE * current_ptr;
  323. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  324. {
  325. current_ptr->overtimeHrs = CALC_OT_HOURS(current_ptr->hours);
  326. }
  327. }
  328.  
  329. void calcGrossPay (EMPLOYEE * head_ptr)
  330. {
  331. float theNormalPay, theOvertimePay;
  332. EMPLOYEE * current_ptr;
  333.  
  334. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  335. {
  336. theNormalPay = CALC_NORMAL_PAY(current_ptr->wageRate,
  337. current_ptr->hours,
  338. current_ptr->overtimeHrs);
  339. theOvertimePay = CALC_OT_PAY(current_ptr->wageRate,
  340. current_ptr->overtimeHrs);
  341. current_ptr->grossPay = theNormalPay + theOvertimePay;
  342. }
  343. }
  344.  
  345. void calcStateTax (EMPLOYEE * head_ptr)
  346. {
  347. EMPLOYEE * current_ptr;
  348.  
  349. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  350. {
  351. if (islower(current_ptr->taxState[0]))
  352. current_ptr->taxState[0] = toupper(current_ptr->taxState[0]);
  353. if (islower(current_ptr->taxState[1]))
  354. current_ptr->taxState[1] = toupper(current_ptr->taxState[1]);
  355.  
  356. if (strcmp(current_ptr->taxState, "MA") == 0)
  357. current_ptr->stateTax = CALC_STATE_TAX(current_ptr->grossPay, MA_TAX_RATE);
  358. else if (strcmp(current_ptr->taxState, "VT") == 0)
  359. current_ptr->stateTax = CALC_STATE_TAX(current_ptr->grossPay, VT_TAX_RATE);
  360. else if (strcmp(current_ptr->taxState, "NH") == 0)
  361. current_ptr->stateTax = CALC_STATE_TAX(current_ptr->grossPay, NH_TAX_RATE);
  362. else if (strcmp(current_ptr->taxState, "CA") == 0)
  363. current_ptr->stateTax = CALC_STATE_TAX(current_ptr->grossPay, CA_TAX_RATE);
  364. else
  365. current_ptr->stateTax = CALC_STATE_TAX(current_ptr->grossPay, DEFAULT_STATE_TAX_RATE);
  366. }
  367. }
  368.  
  369. void calcFedTax (EMPLOYEE * head_ptr)
  370. {
  371. EMPLOYEE * current_ptr;
  372. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  373. {
  374. current_ptr->fedTax = CALC_FED_TAX(current_ptr->grossPay);
  375. }
  376. }
  377.  
  378. void calcNetPay (EMPLOYEE * head_ptr)
  379. {
  380. EMPLOYEE * current_ptr;
  381. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  382. {
  383. current_ptr->netPay = CALC_NET_PAY(current_ptr->grossPay,
  384. current_ptr->stateTax,
  385. current_ptr->fedTax);
  386. }
  387. }
  388.  
  389. void calcEmployeeTotals (EMPLOYEE * head_ptr, TOTALS * emp_totals_ptr)
  390. {
  391. EMPLOYEE * current_ptr;
  392. for (current_ptr = head_ptr; current_ptr; current_ptr = current_ptr->next)
  393. {
  394. emp_totals_ptr->total_wageRate += current_ptr->wageRate;
  395. emp_totals_ptr->total_hours += current_ptr->hours;
  396. emp_totals_ptr->total_overtimeHrs += current_ptr->overtimeHrs;
  397. emp_totals_ptr->total_grossPay += current_ptr->grossPay;
  398. emp_totals_ptr->total_stateTax += current_ptr->stateTax;
  399. emp_totals_ptr->total_fedTax += current_ptr->fedTax;
  400. emp_totals_ptr->total_netPay += current_ptr->netPay;
  401. }
  402. }
  403.  
  404. void calcEmployeeMinMax (EMPLOYEE * head_ptr, MIN_MAX * emp_minMax_ptr)
  405. {
  406. EMPLOYEE * current_ptr = head_ptr;
  407.  
  408. // Initialize with first employee's values
  409. emp_minMax_ptr->min_wageRate = current_ptr->wageRate;
  410. emp_minMax_ptr->min_hours = current_ptr->hours;
  411. emp_minMax_ptr->min_overtimeHrs = current_ptr->overtimeHrs;
  412. emp_minMax_ptr->min_grossPay = current_ptr->grossPay;
  413. emp_minMax_ptr->min_stateTax = current_ptr->stateTax;
  414. emp_minMax_ptr->min_fedTax = current_ptr->fedTax;
  415. emp_minMax_ptr->min_netPay = current_ptr->netPay;
  416.  
  417. emp_minMax_ptr->max_wageRate = current_ptr->wageRate;
  418. emp_minMax_ptr->max_hours = current_ptr->hours;
  419. emp_minMax_ptr->max_overtimeHrs = current_ptr->overtimeHrs;
  420. emp_minMax_ptr->max_grossPay = current_ptr->grossPay;
  421. emp_minMax_ptr->max_stateTax = current_ptr->stateTax;
  422. emp_minMax_ptr->max_fedTax = current_ptr->fedTax;
  423. emp_minMax_ptr->max_netPay = current_ptr->netPay;
  424.  
  425. // Move to next employee
  426. current_ptr = current_ptr->next;
  427.  
  428. // Process remaining employees
  429. for (; current_ptr; current_ptr = current_ptr->next)
  430. {
  431. emp_minMax_ptr->min_wageRate = CALC_MIN(current_ptr->wageRate, emp_minMax_ptr->min_wageRate);
  432. emp_minMax_ptr->max_wageRate = CALC_MAX(current_ptr->wageRate, emp_minMax_ptr->max_wageRate);
  433.  
  434. emp_minMax_ptr->min_hours = CALC_MIN(current_ptr->hours, emp_minMax_ptr->min_hours);
  435. emp_minMax_ptr->max_hours = CALC_MAX(current_ptr->hours, emp_minMax_ptr->max_hours);
  436.  
  437. emp_minMax_ptr->min_overtimeHrs = CALC_MIN(current_ptr->overtimeHrs, emp_minMax_ptr->min_overtimeHrs);
  438. emp_minMax_ptr->max_overtimeHrs = CALC_MAX(current_ptr->overtimeHrs, emp_minMax_ptr->max_overtimeHrs);
  439.  
  440. emp_minMax_ptr->min_grossPay = CALC_MIN(current_ptr->grossPay, emp_minMax_ptr->min_grossPay);
  441. emp_minMax_ptr->max_grossPay = CALC_MAX(current_ptr->grossPay, emp_minMax_ptr->max_grossPay);
  442.  
  443. emp_minMax_ptr->min_stateTax = CALC_MIN(current_ptr->stateTax, emp_minMax_ptr->min_stateTax);
  444. emp_minMax_ptr->max_stateTax = CALC_MAX(current_ptr->stateTax, emp_minMax_ptr->max_stateTax);
  445.  
  446. emp_minMax_ptr->min_fedTax = CALC_MIN(current_ptr->fedTax, emp_minMax_ptr->min_fedTax);
  447. emp_minMax_ptr->max_fedTax = CALC_MAX(current_ptr->fedTax, emp_minMax_ptr->max_fedTax);
  448.  
  449. emp_minMax_ptr->min_netPay = CALC_MIN(current_ptr->netPay, emp_minMax_ptr->min_netPay);
  450. emp_minMax_ptr->max_netPay = CALC_MAX(current_ptr->netPay, emp_minMax_ptr->max_netPay);
  451. }
  452. }
Success #stdin #stdout 0.01s 5288KB
stdin
Standard input is empty
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): 

**** There was no employee input to process ***


 *** End of Program ***