无限循环scanf字符串文本文件c编程

时间:2013-09-20 04:46:17

标签: c string infinite-loop scanf

为什么当我在文本文件中扫描字符串时,它总是进入无限循环?

while(val = fscanf(stdin,"%lf%c",d,c) != EOF)
{if(val==0){//error}
else if(c='\n'){//error print char}
else{//print double}
}

文字档案:

4.5
r5
23
s

我想要的是打印所有内容但是当我到达字符串时它总是给我一个无限循环。

3 个答案:

答案 0 :(得分:4)

scanf()函数系列是一种酷刑测试,不应该对新手程序员造成影响。它们难以准确使用。

分析

甚至忽略代码布局(完全令人震惊 - 这是专业评估)并假设你有这样的变量声明:

double  value;
double *d = &value;
char    newline;
char   *c = &newline;
int     val;

而不是更合理:

double d;
char   c;
int    val;

你的片段中有大量的问题塞进了几行。

while(val = fscanf(stdin,"%lf%c",d,c) != EOF)
{if(val==0){//error}
else if(c='\n'){//error print char}
else{//print double}
}

您已将比较结果分配给val,而不是将fscanf()的返回值分配给val并将其与EOF进行比较。

while ((val = fscanf(stdin, "%lf%c", d, c)) != EOF)

现在代码只是错误的; fscanf()可以返回EOF(通常,但不保证是-1),012,其中只有{ {1}}是您正在寻找的答案。因此,循环条件应为:

2

或者,如果你有更简单的定义,那么它应该是:

while ((val = fscanf(stdin, "%lf%c", d, c)) == 2)

现在你知道读了两个值。循环内的while ((val = fscanf(stdin, "%lf%c", &d, &c)) == 2) 检查现在是多余的;你只能在if (val == 0)时输入循环体。

您可以检查val == 2中的值是否是换行而不是作业的换行符:

*c

(或 if (*c == '\n') ;我们假设你有更简单的声明并忘记了原始代码中的if (c == '\n')个字符。)但是,如果&不是换行符,则会出错,所以实际上它应该是c测试。

!=

循环结束后,您可以测试while ((val = fscanf(stdin, "%lf%c", &d, &c)) == 2) { if (c != '\n') ...print error... else printf("Number = %g\n", d); } vs val == EOF vs val == 0。第一个意味着你已达到EOF或发生了错误;第二个意思是输入中的下一个字符既不是空格也不是有效数字的一部分(例如val == 1.+以外的字母或标点字符)。 -案件是深奥的;它要求文件的结尾发生在后面没有换行符(或任何其他字符)的数字之后。

无限循环

偶然地,无限循环的最可能原因是输入中的无效(非数字,非白色空格)字符。并且,仔细观察,我发现第二行输入上有一个val == 1;这会触发你的代码无限循环。 r将始终返回0,这不是EOF,因此循环继续。 (它无法使用fscanf()读取r,因为它必须首先成功读取数字。)

合成

%c格式将跳过任何前导空格,包括换行符,因此您的代码会尝试确保每行只有一个数字,没有尾随空格。您可能会在此上下文中使用%lfstrtod()做得更好,尽管完全正确使用fgets()并非完全无关紧要。以下代码忽略了strtod()的更精细点。

strtod()

char line[4096]; double d; while (fgets(line, sizeof(line), stdin) != 0) { char *end; d = strtod(line, &end); if (end == line || *end != '\n') ...incorrect format... else printf("Number = %g\n", d); } 返回空指针的唯一原因是您已达到EOF或发生错误。您可能希望在调用fgets()之前设置errno = 0;并在之后检查其值以查找超出范围的数字。

答案 1 :(得分:1)

代码进入无限循环,因为fscanf(stdin,"%lf%c",d,c)尝试读取数字并找到一个字母:r中的r5。如果未能扫描任何内容,则会返回00 != EOF为true,true为val。并while (val)重复。问题是r没有被任何东西消耗,所以下一个`fscanf()会重复尝试同样的结果。

推介

if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
  result = sscanf(buffer, "%lf %c", &d, &c);
  if (result != 1) ; //handle error
}

答案 2 :(得分:0)

一个问题是您不应该尝试扫描换行符。另一个问题是不等于运算符!=高于 precedence而不是赋值,这意味着val是比较的结果。第三个错误是你没有提供一个指向读取值的指针(导致未定义的行为)。

我建议改变这样:

while (scanf("%lf", &d) == 1)
{
    printf("You have read %f\n", d);
}

只要输入是浮点,上面的循环就会循环。