简体   繁体   English

C fscanf从不返回EOF

[英]C fscanf never returns EOF

int findMaxAndMinValues(FILE *file)
{
    int current_number, max_number = INT_MIN, min_number = INT_MAX;
    rewind(file);
    while ( fscanf(file, "%d", &current_number)!=EOF )
    {
        printf("%d \n", current_number);
        if (current_number > max_number) max_number = current_number;
        if (current_number < min_number) min_number = current_number;       
    }
    printf("Max: %d, Min: %d\n", max_number, min_number);
    return 0;
}

So this works fine if the text file is only full of numbers (and spaces/newlines accordingly). 因此,如果文本文件仅包含数字(以及相应的空格/换行符),则此方法很好用。 But if I have a character in it, it starts looping just the last number it read before encountering the character. 但是,如果我有一个字符,它将开始循环播放遇到该字符之前读取的最后一个数字。 This is the text file: 这是文本文件:

1
2
3 4 5
16 
12312
hello  

And the result is just 12312 every line updating endlessly. 结果是12312每行不断更新。
Side question: is there a better way to find min/max values of numbers in a text file? 附带问题:是否有更好的方法来查找文本文件中数字的最小/最大值? Rather than fscanf with %d? 而不是使用%d的fscanf? EDIT:Thanks to the answer, here's how I fixed it: 编辑:感谢答案,这是我的解决方法:

int findMaxAndMinValues(FILE *file)
{
    int current_number, max_number = INT_MIN, min_number = INT_MAX;
    int temp;
    rewind(file);
    while ( (temp=fscanf(file, "%d", &current_number))!=EOF )
    {
        if (!temp) { fgetc(file); }
        else {
            printf("%d \n", current_number);
            if (current_number > max_number) max_number = current_number;
            if (current_number < min_number) min_number = current_number;
        }
    }
    printf("Max: %d, Min: %d\n", max_number, min_number);
    return 0;
}

Read the man page. 阅读手册页。 fscanf() can return other values besides EOF . fscanf()可以返回除EOF之外的其他值。 In particular, if a conversion fails — in particular, if fscanf() encounters a non-numeric character — it will return zero to indicate that nothing was read. 特别是,如果转换失败(特别是fscanf()遇到非数字字符),它将返回零以指示未读取任何内容。

You need to act on this information. 您需要对这些信息采取行动。 Otherwise it will return zero the next time as well. 否则,下次也将返回零。 And the time after that, ad infinitum. 此后的时间是无限的。

The reason your code loops indefinitely if the program input contains a non-number is that fscanf() does not consume input it fails to match, but neither does it return EOF in the event of a matching failure. 如果程序输入中包含非数字,则代码会无限循环的原因是fscanf()不会消耗它无法匹配的输入,但是如果匹配失败,它也不会返回EOF EOF is returned only in the event that the end of the input is reached before either a successful conversion is performed or a matching failure occurs, or if a read error occurs. 仅在成功执行转换或匹配失败或发生读取错误之前到达输入结尾的情况下,才返回EOF (A read error is an I/O error -- quite a different thing from a matching failure .) When your particular program experiences a matching failure, it just loops back around and tries reading the very same input (left waiting to be read) again. (读取错误是一个I / O错误,与匹配失败大不相同。)当您的特定程序遇到匹配失败时,它只会循环返回并尝试读取相同的输入(等待读取)再次。

One way to solve the problem would be to compare fscanf() 's return value with the number of items expected (1), and break from the loop if you see anything else, whether EOF , 0 , or whatever: 解决该问题的一种方法是将fscanf()的返回值与预期的项数(1)进行比较,如果看到其他任何东西(无论EOF0还是其他值),则从循环中中断:

while ( fscanf(file, "%d", &current_number) == 1 ) // ...

Your program would then stop reading numbers when it encounters a non-number; 当程序遇到非数字时,它将停止读取数字。 if you instead wanted it to skip non-numbers then that could be done, too, but it would be a bit more complicated. 如果您想让它跳过非数字,那么也可以这样做,但这会有些复杂。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM