C语言员工薪资程序:Base Pay等计算值无法打印的问题咨询
员工薪资计算程序输出异常问题修复方案
问题根源分析
你的程序能编译但计算字段输出异常,核心原因不是函数返回类型或参数设计问题,而是计算函数调用时机错误,附带数组索引越界的问题:
- 负责计算薪资的
PayRoll和TotalNTax函数,在main中是进入菜单后才调用的——用户选择打印时,BasePay、Taxes等字段还未初始化,输出的是内存垃圾值; - 用户选择员工编号时输入1-5,但数组下标是0-4,直接使用
EmployeeInput[Number]会导致数组越界,触发未定义行为。
修复步骤
1. 调整计算函数调用时机
- 初始录入员工数据后,进入菜单前先调用计算函数,确保初始数据完成计算;
- 修改员工数据后,立即重新调用计算函数,保证更新后的字段同步计算结果。
2. 修正数组索引
在Updating和PrintingOneEmployee函数中,将用户输入的编号减1,转换为合法的数组下标(0-4)。
3. 修复其他细节问题
- 把
Menu函数中的while(x=1)改为while(x==1),避免无限循环; - 优化
Prompts中的换行符处理,替换冗余的scanf为getchar(); - 打印时增加有效员工判断,避免输出未录入的垃圾数据。
修改后的完整代码
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> typedef struct Employee { char Name[20]; float HoursWorked; float HourlyRate; float BasePay; float OverTimePay; float GrossPay; float Taxes; float NetPay; } EmployeeInput; float Menu(struct Employee EmployeeInput[]); float Prompts(struct Employee EmployeeInput[]); void PayRoll(struct Employee EmployeeInput[]); void TotalNTax(struct Employee EmployeeInput[]); void Updating(struct Employee EmployeeInput[]); void PrintingOneEmployee(struct Employee EmployeeInput[]); void PrintingAllEmployees(struct Employee EmployeeInput[]); float Prompts(struct Employee EmployeeInput[]) { for(int i = 0; i < 5; i++) { printf("Name: \n"); scanf("%s", EmployeeInput[i].Name); if (strcmp(EmployeeInput[i].Name, "-1") == 0) { // 清空后续未录入员工的姓名,避免打印垃圾值 strcpy(EmployeeInput[i].Name, ""); break; } printf("Hours Worked: \n"); scanf("%f",&EmployeeInput[i].HoursWorked); if (EmployeeInput[i].HoursWorked == -1) { strcpy(EmployeeInput[i].Name, ""); break; } printf("Hourly Wage: \n"); scanf("%f",&EmployeeInput[i].HourlyRate); if (EmployeeInput[i].HourlyRate == -1) { strcpy(EmployeeInput[i].Name, ""); break; } // 吃掉输入后的换行符 getchar(); } return 0; } void Updating(struct Employee EmployeeInput[]) { int Number; printf("Who would you like to edit? \n"); for(int i=0; i<5; i++){ if(strlen(EmployeeInput[i].Name) == 0) break; printf("%d. %s\n", i+1, EmployeeInput[i].Name); } scanf("%d", &Number); // 转换为合法数组下标 Number -= 1; printf("Enter the New Name: \n"); scanf("%s",EmployeeInput[Number].Name); printf("Enter New Amount of Hours: \n"); scanf("%f", &EmployeeInput[Number].HoursWorked); printf("Enter New Hourly Rate: \n"); scanf("%f", &EmployeeInput[Number].HourlyRate); // 修改后立即重新计算 PayRoll(EmployeeInput); TotalNTax(EmployeeInput); } float Menu(struct Employee EmployeeInput[]) { int Choice; int x =1; // 修正为判断相等 while (x == 1) { printf("\n1. Update an existing employee\n"); printf("2. Print One Employee \n"); printf("3. Print All Employees \n"); printf("4. Quit \n"); scanf("%d", &Choice); switch(Choice) { case 1: Updating(EmployeeInput); break; case 2: PrintingOneEmployee(EmployeeInput); break; case 3: PrintingAllEmployees(EmployeeInput); break; case 4: return 0; default: printf("Invalid choice, try again.\n"); } } return 0; } void PayRoll(struct Employee EmployeeInput[]) { for(int i = 0; i < 5; i++) { // 跳过未录入的员工 if(strlen(EmployeeInput[i].Name) == 0) continue; if(EmployeeInput[i].HoursWorked < 40) { EmployeeInput[i].BasePay = EmployeeInput[i].HourlyRate * EmployeeInput[i].HoursWorked; EmployeeInput[i].GrossPay = EmployeeInput[i].BasePay; EmployeeInput[i].OverTimePay = 0; } else if(EmployeeInput[i].HoursWorked >= 40) { float overtimehours = EmployeeInput[i].HoursWorked - 40; EmployeeInput[i].OverTimePay = (overtimehours * EmployeeInput[i].HourlyRate) * 1.5; EmployeeInput[i].BasePay = EmployeeInput[i].HourlyRate * 40; EmployeeInput[i].GrossPay = EmployeeInput[i].BasePay + EmployeeInput[i].OverTimePay; } } } void TotalNTax(struct Employee EmployeeInput[]) { for(int i = 0; i < 5; i++) { if(strlen(EmployeeInput[i].Name) == 0) continue; EmployeeInput[i].Taxes = EmployeeInput[i].GrossPay * 0.2; EmployeeInput[i].NetPay = EmployeeInput[i].GrossPay - EmployeeInput[i].Taxes; } } int main() { struct Employee EmployeeNumber[5]; // 初始化结构体数组,避免垃圾值 memset(EmployeeNumber, 0, sizeof(EmployeeNumber)); Prompts(EmployeeNumber); // 初始数据先计算 PayRoll(EmployeeNumber); TotalNTax(EmployeeNumber); Menu(EmployeeNumber); return 0; } void PrintingOneEmployee(struct Employee EmployeeInput[]) { int Number; printf("Please enter the number of the employee you wish to print:\n"); for(int i=0; i<5; i++){ if(strlen(EmployeeInput[i].Name) == 0) break; printf("%d. %s\n", i+1, EmployeeInput[i].Name); } scanf("%d", &Number); Number -= 1; if(strlen(EmployeeInput[Number].Name) == 0){ printf("Invalid employee number.\n"); return; } printf("\nName: %s\n", EmployeeInput[Number].Name); printf("Hours worked: %0.2f\n", EmployeeInput[Number].HoursWorked); printf("Hourly rate: %0.2f\n", EmployeeInput[Number].HourlyRate); printf("Base pay: %0.2f\n", EmployeeInput[Number].BasePay); printf("Overtime pay: %0.2f\n", EmployeeInput[Number].OverTimePay); printf("Gross pay: %0.2f\n", EmployeeInput[Number].GrossPay); printf("Taxes paid: %0.2f\n", EmployeeInput[Number].Taxes); printf("Net pay: %0.2f\n", EmployeeInput[Number].NetPay); } void PrintingAllEmployees(struct Employee EmployeeInput[]) { printf("\n--- All Employees Payroll ---\n"); for(int i = 0; i < 5; i++) { if(strlen(EmployeeInput[i].Name) == 0) break; printf("\nName: %s\n", EmployeeInput[i].Name); printf("Hours worked: %0.2f\n", EmployeeInput[i].HoursWorked); printf("Hourly rate: %0.2f\n", EmployeeInput[i].HourlyRate); printf("Base pay: %0.2f\n", EmployeeInput[i].BasePay); printf("Overtime pay: %0.2f\n", EmployeeInput[i].OverTimePay); printf("Gross pay: %0.2f\n", EmployeeInput[i].GrossPay); printf("Taxes paid: %0.2f\n", EmployeeInput[i].Taxes); printf("Net pay: %0.2f\n", EmployeeInput[i].NetPay); } }
内容的提问来源于stack exchange,提问作者Harvey Yang
相关产品推荐
相关产品推荐

