gpt4 book ai didi

c - fscanf 在文件末尾返回 3 而不是 -1 (EOF)

转载 作者:太空宇宙 更新时间:2023-11-04 06:12:08 25 4
gpt4 key购买 nike

所以有一个我正在使用 fscanf() 的文件。我在我的代码中设置了一个条件,即当 (fscanf(...) == EOF 时,程序需要跳出我正在执行的函数当前在。问题是,在文件中没有更多文本行的任何情况下,永远不会满足此条件。EOF 始终为 -1,而每次有一行代码时 fscanf(...) 返回 4 , 和 3 当它没有任何东西可以搜索时(而不是 -1)。如果我添加一行类似于其他代码的代码,我将简单地得到一个返回 4 的 fscanf() 实例,然后再次,它会给我一个 3。

可能是什么问题?提前致谢!

示例文本文件内容:

CHRISTOU GIORGOS,140,​​VAS。奥尔加斯 112

MALAKOU MALAKOS,150,DRAS。巴加斯 12

TSIKOU GIJRAN,140,JABS。德拉格斯 1

TSIKOU BIRBAN,140,JABS。德拉格斯 1

DELHDHMHTRIOU SPYROS,50,速度。巴加斯 62

FOX SIN,40,BAN。忍者1

代码:

#include <stdio.h>
#define M 100

typedef struct {
char name[30];
int apousies;
} studentT;

void readInput (FILE* infile, studentT students[], int *pApousies, int *pStudents);


int main()
{
char inputfilename[30];
FILE* infile;

while (1) {
printf("Input file name :");
gets(inputfilename);

infile = fopen(inputfilename, "r");

if (infile != NULL) break;
printf("Cannot open input file %s. Try again.\n", inputfilename);
}

studentT students[M];
int numberOfStudents = 0, numberOfApousies = 0;
readInput(infile, students, &numberOfApousies, &numberOfStudents);
fclose(infile);
return 0;
}

void readInput (FILE* infile, studentT students[], int *pApousies, int *pStudents)
{
int nscan, apousies, studcount, apouscount, line;
char name[30], comments[68], termch;

line = 0;
while (1)
{
nscan = fscanf(infile, "%30[^,], %d, %68[^\n]%c", name, &apousies, comments, &termch);
/* printf("onoma: %s apousies: %d sxolia: %s terma: %c\n", name, apousies, comments, termch);
printf("%d\n", nscan);
printf("%d\n", EOF);*/
if (nscan == EOF) break;
line++;

if (nscan != 4 || termch != '\n')
{
printf("Error in line %d. Program termination\n", line);
exit(1);
}
}
}

最佳答案

fscanf returns 3 instead of -1 (EOF) at the end of the file

因为最后一行缺少'\n'


OP 的代码与下面代码生成的 “tmp.txt” 一起“工作”。

fscanf() 很难正确使用。使用 fgets() 更容易编码和调试。讨论如下。


"%30[^,]" 允许 char name[30] 太多。使用 char name[30+1]"%29[^,]"

OP 的方法很容易失败,因为看似很小的解析问题,例如最后一行缺少 '\n'。在这样的故障之后,使用 fscanf()

恢复非常困难

调试:重要的是,在代码确保 nscan >= 4

之前,不应尝试以下打印
if (nscan >= 4) // add
printf("onoma: %s apousies: %d sxolia: %s terma: %c\n", name, apousies, comments, termch);

相反,请使用 fgets()。对于面向的数据,这确实是最好的第一步。

fscanf() 使用和处理错误具有挑战性。使用 fgets() 读取 然后解析要简单得多。

使用 "%n" 是检测所有行是否已解析的好方法。

#include <stdio.h>
#include <stdlib.h>
#define M 100

typedef struct {
char name[30];
int apousies;
} studentT;

void readInput(FILE* infile, studentT students[], int *pApousies,
int *pStudents) {
(void) students;
(void) pApousies;
(void) pStudents;
int line = 0;
char buf[200];
while (fgets(buf, sizeof buf, infile)) {
int apousies;
char name[30], comments[68];
int n = 0;

line++;
sscanf(buf, " %29[^,],%d , %67[^\n] %n", name, &apousies, comments, &n);
if (n == 0 || buf[n]) {
fprintf(stderr, "Error in line %d <%s>. Program termination\n", line, buf);
exit(1);
}
printf("Success %d <%s> %d <%s>\n", line, name, apousies, comments);
}
}

示例使用

int main() {
FILE *f = fopen("tmp.txt", "w");
fputs("CHRISTOU GIORGOS,140,VAS. OLGAS 112\n"
"MALAKOU MALAKOS,150,DRAS. BAGAS 12\n"
"TSIKOU GIJRAN,140,JABS. DRALGAS 1\n"
"TSIKOU BIRBAN,140,JABS. DRALGAS 1\n"
"DELHDHMHTRIOU SPYROS,50,SPEED. BAGAS 62\n"
"FOX SIN,40,BAN. NINJA 1\n", f);
fclose(f);

f = fopen("tmp.txt", "r");
studentT st[M];
readInput(f, st, NULL, NULL);
fclose(f);
}

输出

Success 1 <CHRISTOU GIORGOS> 140 <VAS. OLGAS 112>
Success 2 <MALAKOU MALAKOS> 150 <DRAS. BAGAS 12>
Success 3 <TSIKOU GIJRAN> 140 <JABS. DRALGAS 1>
Success 4 <TSIKOU BIRBAN> 140 <JABS. DRALGAS 1>
Success 5 <DELHDHMHTRIOU SPYROS> 50 <SPEED. BAGAS 62>
Success 6 <FOX SIN> 40 <BAN. NINJA 1>

关于c - fscanf 在文件末尾返回 3 而不是 -1 (EOF),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54014577/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com