我正在编写一个C程序,该程序逐行读取具有特定格式的文本文件。
我做了一个do { ... } while(!feof(file));
循环,但它总是循环太多次。这是一个问题,因为我已经做到了,所以当我的程序希望读取某些内容但什么也没得到时,它会引发错误,所以现在每次都引发一个错误,因为它到达了循环顶部的文件末尾
我认为这是因为eof标志仅在您尝试fscanf某个东西时触发,但那里什么也没有。我该如何解决这个问题?将最后一个fscanf放在底部是行不通的,因为如果不在文件末尾,则它将使所有读数弄乱,并将所有内容移位一个。
do {
read = fscanf(/*...*/);
if (read != 1)
{
return -1;
}
// Read grades
read = fscanf(/*...*/);
if (read != 3)
{
return -1;
}
// Read student kind
int student_kind = 0;
read = fscanf(/*...*/);
if (read != 1)
{
return -1;
}
if (student_kind < 0 | student_kind > 2)
{
printf("Invalid student kind");
return -1;
}
SCIPER sciper_teammate = 0;
read = fscanf(/*...*/);
if (read != 1)
{
return -1;
}
} while (!feof(file));
答案 0 :(得分:0)
由于您使用的是fscanf()
:
§7.21.6.2-16 -如果在第一次转换(如果有)完成之前发生输入失败,则
fscanf
函数将返回宏EOF
的值。否则,该函数将返回分配的输入项目数,如果早期匹配失败,该数目可能少于所提供的输入项数,甚至为零。
EOF
是一个值为-1
的宏,就其发生的原因而言,它本身是无法区分的。
出于这种区别,§7.21.6.2-19 建议对文件结尾使用feof()
,对I / O错误使用ferror()
:
示例3 要从
stdin
反复接受数量,计量单位和商品名称:#include<stdio.h> /*...*/ int count; floatquant; charunits[21], item[21]; do { count = fscanf(stdin, "%f%20sof%20s", &quant, units, item); fscanf(stdin,"%*[^\n]"); //here discarding unread characters in the buffer } while(!feof(stdin) && !ferror(stdin));
这应该适合您的情况,但个人而言。我不喜欢这种方法,因为如果您输入的值少于fscanf
所期望的值,这将失败,通常会导致无限循环。
读取格式化输入时,我的方法是检查输入值。
对于2个整数的样本输入,您可以执行以下操作:
#include <stdio.h>
int main()
{
int a, b;
FILE* file;
if(!(file = fopen("file.txt", "r"))){
return 1;
}
while(fscanf(file, "%d %d", &a, &b) == 2){ //read each 2 integers in the file, stop when condition fails, i.e. there are nothing else to read or the read input is not an integer
printf("%d %d\n", a, b);
}
}
这解决了所有输入故障,并且会因I / O错误,EOF和错误输入而终止循环。