fscanf()陷入无限循环 [英] fscanf() stucks in an infinite loop

查看:261
本文介绍了fscanf()陷入无限循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含整数矩阵的文件,如下所示:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆