fscanf()陷入无限循环 [英] fscanf() stucks in an infinite loop
问题描述
我有一个包含整数矩阵的文件,如下所示:
I've got a file containing a matrix of integers like this:
1 2 -5
0 2 4
-2 –1 3
我需要知道矩阵中有多少个元素(在本例中为9).
I need to know how many elements there are in the matrix (in this case 9).
计算元素数量的代码如下:
The code that calculates the number of elements is the following:
while(!feof(pFile)) {
fscanf(pFile, "%d", &voidElement);
elements++;
}
由于某些原因,当fscanf
读取包含矩阵的文件中的数字-2
时,代码进入循环.
For some reasons, the code enters a loop when the fscanf
reads the number -2
in the file containing the matrix.
感谢您的帮助.
推荐答案
这是一个看起来像您的小程序,但是可以运行(不会卡住-与我的输入文件相对应).但是,您会发现它有问题-请继续阅读:
Here is a small program that looks like yours, but works (doesn't get stuck - with my input file). However you will see that it has a problem - keep reading:
#include <stdio.h>
int main(void) {
int i, el=0;
FILE* fp;
fp = fopen("nine.txt","r");
while(!feof(fp)) {
fscanf(fp, "%d", &i);
el++;
printf("element %d = %d\n", el, i);
}
fclose(fp);
}
输出:
element 1 = 1
element 2 = 2
element 3 = -5
element 4 = 0
element 5 = 2
element 6 = 4
element 7 = -2
element 8 = -1
element 9 = 3
element 10 = 3
换句话说-这样做将比预期得到更多的元素-因为在尝试读取文件末尾之前未设置feof
标志.
In other words - doing this you will get ONE MORE ELEMENT THAN YOU EXPECTED - because the feof
flag is not set until you TRY TO READ PAST THE END OF THE FILE.
换句话说-您的方法不好;实际上,您应该检查fscanf
是否成功,并仅对那些(成功读取)进行计数.
In other words - your method is not great; you actually should check whether the fscanf
succeeded, and count those (successful reads) only.
更好的技术是:
#include <stdio.h>
int main(void) {
int i, el=0;
FILE* fp;
fp = fopen("nine.txt","r");
while(1) {
if(fscanf(fp, "%d", &i)!=1) break;
el++;
printf("element %d = %d\n", el, i);
}
fclose(fp);
}
还有一件事情-如果fscanf
由于任何原因而失败(也许文件中有坏字符),它将永远不会到达文件的末尾,并且EOF标记也将永远不会被设置.这可能就是为什么您的代码实际上进入了无限循环的原因-以及为什么第二种方法(当fscanf
未成功读取准确的一个值时退出循环)的原因.
One more thing - if the fscanf
fails for any reason (maybe there is a bad character in the file), it will never get to the end of the file and the EOF marker will never be set. This is probably why your code was actually going into an infinite loop - and why the second method (which exits the loop when fscanf
did not successfully read exactly one value) will work.
编辑,当我使用上面的数字(最初我只是将数字键入文本文件)时,在下面的注释中按照建议进行操作(获取输入文件并进行十六进制转储)一切正常…)我看到了以下内容:
EDIT when I followed the advice in my own comment below (take the input file and do a hex dump) using the numbers you had above (originally I had just typed the numbers into a text file and things worked fine…) I saw the following:
hexdump -C typedNumbers.txt
00000000 31 20 32 20 2d 35 0a 30 20 32 20 34 0a 2d 32 20 |1 2 -5.0 2 4.-2 |
00000010 2d 31 20 33 0a |-1 3.|
00000015
hexdump -C copiedNumbers.txt
00000000 31 20 32 20 2d 35 0a 30 20 32 20 34 0a 2d 32 20 |1 2 -5.0 2 4.-2 |
00000010 e2 80 93 31 20 33 0a |...1 3.|
00000017
请注意,两个文件的第一行相同-但是第二个文件(您的原始文件)的第二行中有不可打印的"字节.特别是,这些字节是
Note that the first line is identical in both files - but there are "unprintable" bytes in the second line of the second file (your original file). In particular, the bytes are
e2 80 93 before 31
代替
2d 31
看到三个字符最终由一个单个的破折号表示,这使我感到困惑-我必须承认我不知道该怎么做.但是,正如我在较早版本的答案中推测的那样,有您的坏的隐藏字符".
It puzzles me to see that three characters end up being represented by a single emdash - I must admit I don't understand how that is done. But there are your "bad hidden characters" as I surmised in an earlier version of my answer.
这篇关于fscanf()陷入无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!