我无法用试图从txt文件读取的数据填充数组。因此,我使用以下代码尝试读取以下txt文件。
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
我使用的代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.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
} Employee;
int main()
{
Employee payroll[200];
int i = 0;
FILE*infile;
infile = fopen("payroll.txt", "r");
//fscanf loop that will fill payroll array with data from file
while (!feof(infile))
{
fscanf(infile, " %s", &payroll[i].name); //Reading name
fscanf(infile, "%c", &payroll[i].title); //Reading title
fscanf(infile, "%lf", &payroll[i].hours_worked); //Reading hours worked
fscanf(infile, "%lf", &payroll[i].payrate); //Reading pay rate
++i;
}
printf("%d\n", i);
//loop that tests to make sure array was correctly filled
for (i = 0; i < 4; ++i)
{
printf("%s\n", payroll[i].name);
printf("%c\n", payroll[i].title);
printf("%lf\n", payroll[i].hours_worked);
printf("%lf\n", payroll[i].payrate);
}
fclose(infile);
system("pause");
return 0;
}
所以我意识到我的问题必须是第一个读取字符串名称的fscanf,因为一旦fscanf读取了读取名称的空白,fscanf就停止了,所以我切换到fgets():
fgets(payroll[i].name, 100, infile);
但是那仍然不能给我正确的结果。
请帮助
edit:因此,我的fscanfs显然存在其他问题,因为如果我将txt文件编辑为此以消除空格,则可以使用fscanf:
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
我正在使用此代码的位置:
while (!feof(infile))
{
fscanf(infile, " %s", &payroll[i].name); //Reading name
fscanf(infile, "%c", &payroll[i].title); //Reading title
fscanf(infile, "%lf", &payroll[i].hours_worked); //Reading hours worked
fscanf(infile, "%lf", &payroll[i].payrate); //Reading pay rate
++i;
}
如果打印结果像这样疯狂,我仍然会收到错误消息: https://i.stack.imgur.com/x6l7a.png
答案 0 :(得分:2)
使用fgets
和sscanf
来控制输入和数据提取比使用fscanf
来控制输入和数据提取要容易得多,像这样,以及其他一些注释性的更改和添加。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define RECORDS 200 // better not to hard-code inline
#define NAMELEN 99
typedef struct employee {
char name[NAMELEN+1]; // 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
} Employee;
int main(void)
{
char instr[256];
Employee payroll[RECORDS];
int records = 0; // `i` was a poor choice of name
FILE *infile;
infile = fopen("payroll.txt", "r");
if(infile == NULL) {
perror("Could not open file");
exit(1); // check file opened
}
// loop that will fill payroll array with data from file
while(fgets(instr, sizeof instr, infile) != NULL) {
// name
if(records >= RECORDS) {
perror("Too many records");
exit(1);
}
instr[ strcspn(instr, "\r\n") ] = 0; // remove trailing newline etc
instr[NAMELEN] = 0; // truncate long name
strcpy(payroll[records].name, instr);
// title
if(fgets(instr, sizeof instr, infile) == NULL) {
perror("Incomplete data");
exit(1);
}
payroll[records].title = instr[0];
// hours worked
if(fgets(instr, sizeof instr, infile) == NULL) {
perror("Incomplete data");
exit(1);
}
if(sscanf(instr, "%lf", &payroll[records].hours_worked) != 1) {
perror("Error in hours worked");
exit(1);
}
// pay rate
if(fgets(instr, sizeof instr, infile) == NULL) {
perror("Incomplete data");
exit(1);
}
if(sscanf(instr, "%lf", &payroll[records].payrate) != 1) {
perror("Error in pay rate");
exit(1);
}
++records;
}
printf("%d records\n", records);
//loop that tests to make sure array was correctly filled
for (int i = 0; i < records; ++i) { // use the variable
printf("%s\n", payroll[i].name);
printf("%c\n", payroll[i].title);
printf("%.2f\n", payroll[i].hours_worked); // %f not %lf
printf("%.2f\n", payroll[i].payrate); // specify dec places
printf("\n");
}
fclose(infile);
return 0;
}
程序输出:
4 records Smith,Susan B 80.00 17.76
Sanders,Fred M 87.25 23.45
Kerr,Heidi M 80.00 47.86
Russo,Rick B 83.75 12.15
请注意,feof
不会检查文件结尾。它通过事先读取文件末尾(没有数据)来检查您是否出错。
fscanf
,则为
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define RECORDS 200 // better not to hard-code inline
#define NAMELEN 99
typedef struct employee {
char name[NAMELEN+1]; // 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
} Employee;
int main(void)
{
Employee payroll[RECORDS];
int records = 0; // `i` was a poor choice of name
FILE *infile;
infile = fopen("payroll.txt", "r");
if(infile == NULL) {
perror("Could not open file");
exit(1); // check file opened
}
// loop that will fill payroll array with data from file
while(fscanf(infile, " %99[^\n] %c%lf%lf", // spaces remove the newlines
payroll[records].name, // no `&`
&payroll[records].title,
&payroll[records].hours_worked,
&payroll[records].payrate) == 4) {
++records;
}
printf("%d records\n", records);
//loop that tests to make sure array was correctly filled
for (int i = 0; i < records; ++i) { // use the variable
printf("%s\n", payroll[i].name);
printf("%c\n", payroll[i].title);
printf("%.2f\n", payroll[i].hours_worked); // %f not %lf
printf("%.2f\n", payroll[i].payrate); // specify dec places
printf("\n");
}
fclose(infile);
return 0;
}