使用 fscanf 读取文件时丢失数据

losing data when reading a file with fscanf

使用这样的部分代码:

fscanf(f1, "%d", &n);
while(!feof(f1)){
...
fscanf(f1, "%d", &n);}

它错过了文件的最后一行(遇到 EOF)。我该如何解决?

我找到的唯一解决方案是:

if (fscanf(f1, "%d", &n)!=EOF){
rewind(f1);
do{
...
fscanf(f1, "%d", &n);
}while(!feof(f1));
}

您将 fscanf 放在循环的末尾。 fscanf 读取直到确定数字已完成。如果输入文件的最后一个字符是数字(与 space 或新行相对),在解析最后一行时(有些人会称不以新行结尾的行 "incomplete last line"),fscanf命中 EOF 试图找到数字的末尾,所以 feof 为真,因为已经命中 EOF。

您不应该检查 feof,而是检查 fscanf 的 return 代码。它会告诉你是否有一些数字可以解析为数字。

假设您的文件包含 "11\n23"

f = fopen(...);
result = fscanf(f, "%d", &i);
// result == 1, because one variable has been read
// i == 11, because that's the first number
// file pointer is past the '\n', because '\n'
//   had to be read to find out the number is not
//   something like 110
//   The '\n' itself has been put back using ungetc
// feof(f) == 0, because nothing tried to read past EOF

result = fscanf(f, "%d", &i);
// result == 1, because one variable has been read by this call
// i == 23 (obviously)
// file pointer is at EOF (it can't go further)
// feof(f) == 1, because fscanf tried to read past
//   the '3' to check whether there were extra
//   characters.

//  (Your loop terminates here, because feof(f) is true

result = fscanf(f, "%d", &i);
// result == EOF (error before first variable)
// i is likely unchanged. I am unsure whether this
//   is guaranteed by the language definition
// file pointer unchanged
// feof(f) still true

// You should terminate processing *NOW*, because
// return is no longer one.