fscanf - 如何知道 EOF 是文件结尾还是 reading/another 错误?

fscanf - How to know if EOF means end of file or reading/another error?

我有一个关于I/O的C语言的问题,如何才能知道我的文件讲完了还是读不出来(或者有问题)在这两种情况下, fscanf returns EOF ?

根据 fscanf() return 值:

ISO/IEC 9899:2017

§ 7.21.6.2 - 16 - The fscanf function returns the value of the macro EOF if an input failure occurs before the first conversion (if any) has completed. Otherwise, the function returns the number of input items assigned, which can be fewer than provided for, or even zero, in the event of an early matching failure.

EOF是一个值为-1的宏,它本身并不能区分它出现的原因。

为了这个区分 § 7.21.6.2 - 19 推荐使用 feof() for end-of-file and ferror() 用于 I/O 错误:

EXAMPLE 3 To accept repeatedly from stdin a quantity, a unit of measure, and an item name:

#include<stdio.h> 

/*...*/

int count; floatquant; 
charunits[21],  item[21]; 

do { 
    count = fscanf(stdin, "%f%20sof%20s", &quant, units, item);
    fscanf(stdin,"%*[^\n]"); 
} while(!feof(stdin) && !ferror(stdin));

我在读取格式化输入时的常用方法是检查输入的值。对于 2 个整数的示例输入,您可以执行以下操作:

int a, b;
FILE* file;
//open file to read
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
    //...handle inputs
}

这种读取是安全的,并且解决了所有失败场景,因为它适用于错误输入和 "end of file"。

不要 fscanf() 的 return 值,除此之外 feof() and ferror() 调用 fscanf() 之后:

FILE* file;
if((file == fopen("file.txt","r")) == NULL)
{
    fprintf(stderr, "File could not be opened!");
    return EXIT_FAILURE;
}

char buf;

/******************************************************************************/

while(fscanf(file,"%c",buf) == 1) {     // checks if an error was happen, else 
                                        // iterate to catching characters.
   /* handling of read character */
}

if(ferror(file))                        // checks if an I/O error occurred.
{
   // I/O error handling
   fprintf(stderr,"Input/Output error at reading file!");
   clearerr(file);
   // Further actions
}
else if(feof(file))                     // checks if the end of the file is reached.       
{
   // end of file handling
   fprintf(stderr,"Reached End of File!");
   clearerr(file);
   // Further actions
}

/******************************************************************************/

if(fclose(file) != 0)
{
    fprintf(stderr, "File could not be closed properly!");
    return EXIT_FAILURE;
}