我正在尝试扫描一个txt文件,根据是否满足某些条件,我想将其打印到另一个txt文件中。下面是我的主要函数:
#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: $%.2lfn average: $%.3lfnMAx: $%.3lfn 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
问题是我没想到它会打印出那么多的总数,平均值,最大值和最小值都是0。
许多许多错误(您的编译器应该至少警告您其中一些错误)
fscanf(infile, "%s", &payroll[i].name) )
不传递指向%s的字符串指针,应该是
fscanf(infile, "%s", payroll[i].name) )
使用%c作为字符,所以
fscanf(infile, "%s", &payroll[i].title);
应该
fscanf(infile, " %c", &payroll[i].title);
注意前导空间占用了缓冲区
中的CRLFfscanf(infile, "%s", &payroll[i].hours_worked);
你在这里使用%s表示你想要一个字符串,但将其读入双精度类型,下一个类似,应该是
fscanf(infile, "%lf", &payroll[i].hours_worked);
这里
fprintf(outfile, "total: $%.2lfn average: $%.2lfnMAx: $%.2lfn Min: $%.2lf", total, average, max, min);
你使用%lf输出int,应该是
fprintf(outfile, "total: $%.2lfn average: $%dnMAx: $%dn Min: $%d", total, average, max, min);
总是测试函数的返回值,特别是IO (fscanf)
也读这个关于while !eof
为什么iostream::eof在循环条件中(即:' while (!stream.eof()) ')被认为是错误的?
接下来,当使用%s读取字符串时,fscanf
读取到第一个空白
这
if (fscanf(infile, "%s", payroll[i].name) == NULL)
break;
当美联储
Smith, Susan
(注意','后面的空格)实际上读作
"Smith,"
插入名称
下一次读(char类型的)取'S',然后读(double类型的)尝试读'mith',这是行不通的。
你应该用fgets
代替,读取整行
if (fgets(payroll[i].name, 100, infile) == NULL)
break;
请注意正确检测eof的更改(我将while(1)
用于循环)
还需要在最后一次双读之后添加fgetc(infile)
,以便在下一个fgets之前吃掉cr lf
现在
total: $1283.34
average: $320
MAx: $5360
Min: $1283
跑题了,但是…
你为什么要"加码"?你的代码是复制/粘贴/调整代码块的吗?
所有这些:
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;
}
的存在只是为了使用一个不同的常数乘数。可以简化为:
Employee *e = payroll + i;
e->payment = e->hours_worked * e->payrate;
if (e->hours_worked > 40)
e->payment += (e->title == 'B') ? 0.5 : 0.8 * e->payrate * (e->hours_worked - 40);
员工按工作时间支付标准工资。
加班时间(超过40小时)按适当的加班费支付。
编写更少但更有效的代码。
读者不应该被迫扫描大块的重复代码,试图找出它们之间的微小差异。
(事实上,计算应该被分解到一个单独的函数中,将计算从"流程"中隔离出来;读取记录并将其他值制成表)