You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言main函数执行异常:薪资计算程序输出结果错误求助

薪资计算程序异常问题排查与修复

问题现象

读取payroll.txt文件,按员工职位('B'或'M')的规则计算薪资并输出到paid.txt后,出现total数值异常巨大,average、max、min均为0的错误。


原代码与文件内容

main函数原代码

#include "Header.h"

int main(void) {
    int payment=0, hours_worked = 0, rate_per_hour = 0, overtime = 0, total_payment, min = 0, max = 0, average = 0;
    total_payment=0;
    double total = 0;
    Employee payroll[200];

    FILE* infile = fopen("payroll.txt", "r");
    FILE* outfile = fopen("paid.txt", "w");


    int i = 0;
    while (!feof(infile)) {
        fscanf(infile, "%s", &payroll[i].name);
        fscanf(infile, "%s", &payroll[i].title);
        fscanf(infile, "%s", &payroll[i].hours_worked);
        fscanf(infile, "%s", &payroll[i].payrate);

        if (payroll[i].title == 'B') {
            if (payroll[i].hours_worked > 40) {
                payroll[i].payment = 40 * payroll[i].payrate;
                payroll[i].payment += (1.5 * payroll[i].payrate * (payroll[i].hours_worked - 40));
            }
            else
                payroll[i].payment = payroll[i].hours_worked * payroll[i].payrate;
        }
        else {
            if (payroll[i].hours_worked > 40) {
                payroll[i].payment = 40 * payroll[i].payrate;
                payroll[i].payment += (1.8 * payroll[i].payrate * (payroll[i].hours_worked - 40));
            }
            else
                payroll[i].payment = payroll[i].hours_worked * payroll[i].payrate;
        }
        if (i == 0)
            min = payroll[i].payment;
        total = +payroll[i].payment;
        if (min > payroll[i].payment)
            min = payroll[i].payment;
        if (max < payroll[i].payment)
            max = payroll[i].payment;
        i++;
    }
    average = total / i; 
    fprintf(outfile, "total: $%.2lf\n average: $%.3lf\nMAx: $%.3lf\n Min: $%.2lf", total, average, max, min);

    fclose(infile);
    fclose(outfile);
    return 0;
}

头文件原代码

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>


typedef struct employee
{
       char name[100];      // employee's name - last, first
       char title;          // title 'B' or 'M'
       double hours_worked; // total number of hours worked
       double payrate;      // pay rate per hour
       double payment;      // total payment for the pay period – you will compute!
} Employee;

#endif

payroll.txt内容

Smith, Susan
B
80.0
17.76
Sanders, Fred
M
87.25
23.45
Kerr, Heidi
M
80.0
47.86
Russo, Rick
B
83.75
12.15

异常输出paid.txt

total: $8098405204118553210089249756384123022462475737784054204141978203412550137716411406580975068756992904139218004071573362835456.00
 average: $0.000
MAx: $0.000
 Min: $0.00

错误原因分析

  • 格式符不匹配:
    • 读取单个字符title用%s,会读取后续换行符导致title值错误,应改为%c并跳过前置换行;
    • 读取double类型的hours_worked和payrate用%s,导致内存写入乱码,出现超大数值。
  • 累加逻辑错误:total = +payroll[i].payment;是赋值而非累加,正确写法为total += payroll[i].payment;。
  • 变量类型不匹配:min、max、average定义为int类型,无法适配double类型的薪资数据,导致精度丢失和比较逻辑失效。
  • feof循环缺陷:while (!feof(infile))会在文件读取结束后仍执行一次循环,处理无效数据。
  • 姓名读取不完整:%s只能读取到空格前的字符,无法读取含空格的完整姓名,应使用%[^\n]读取整行。

修正后的代码

main函数修正版

#include "Header.h"

int main(void) {
    double total = 0, min = 0, max = 0, average = 0;
    Employee payroll[200];

    FILE* infile = fopen("payroll.txt", "r");
    FILE* outfile = fopen("paid.txt", "w");

    if (!infile || !outfile) {
        printf("文件打开失败");
        return 1;
    }

    int i = 0;
    // 读取每组数据:姓名、职位、工时、时薪,返回4表示读取成功
    while (fscanf(infile, "%[^\n]%*c %c%*c %lf%*c %lf%*c", 
                  payroll[i].name, &payroll[i].title, 
                  &payroll[i].hours_worked, &payroll[i].payrate) == 4) {

        if (payroll[i].title == 'B') {
            if (payroll[i].hours_worked > 40) {
                payroll[i].payment = 40 * payroll[i].payrate;
                payroll[i].payment += (1.5 * payroll[i].payrate * (payroll[i].hours_worked - 40));
            } else {
                payroll[i].payment = payroll[i].hours_worked * payroll[i].payrate;
            }
        } else {
            if (payroll[i].hours_worked > 40) {
                payroll[i].payment = 40 * payroll[i].payrate;
                payroll[i].payment += (1.8 * payroll[i].payrate * (payroll[i].hours_worked - 40));
            } else {
                payroll[i].payment = payroll[i].hours_worked * payroll[i].payrate;
            }
        }

        if (i == 0) {
            min = payroll[i].payment;
            max = payroll[i].payment;
        }
        total += payroll[i].payment;
        if (min > payroll[i].payment) min = payroll[i].payment;
        if (max < payroll[i].payment) max = payroll[i].payment;
        i++;
    }

    if (i > 0) {
        average = total / i;
        fprintf(outfile, "total: $%.2lf\n average: $%.3lf\nMax: $%.3lf\n Min: $%.2lf", 
                total, average, max, min);
    } else {
        fprintf(outfile, "未读取到有效员工数据");
    }

    fclose(infile);
    fclose(outfile);
    return 0;
}

头文件(无需修改)

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

typedef struct employee
{
       char name[100];      // employee's name - last, first
       char title;          // title 'B' or 'M'
       double hours_worked; // total number of hours worked
       double payrate;      // pay rate per hour
       double payment;      // total payment for the pay period – you will compute!
} Employee;

#endif

修正后输出结果(paid.txt)

total: $10612.64
 average: $2653.160
Max: $4625.72
 Min: $1760.25

内容的提问来源于stack exchange,提问作者MoeSonOfJoe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 07:30:39