无限循环fscanf字符串文本文件c编程
为什么当我扫描文本文件中的字符串时,它总是进入无限循环无限循环fscanf字符串文本文件c编程,c,string,infinite-loop,scanf,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 我想打印所有内容,但当我到达字符串时,它总是给我一个无限循环。一个问题是,你不应该尝试扫描换行符。另一个问题是不相等运算符=的值高于赋值,这意味着val
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
我想打印所有内容,但当我到达字符串时,它总是给我一个无限循环。一个问题是,你不应该尝试扫描换行符。另一个问题是不相等运算符
=
的值高于赋值,这意味着val
是比较的结果。第三个错误是您没有提供一个指针来读取值(导致未定义的行为)
我建议这样改变:
while (scanf("%lf", &d) == 1)
{
printf("You have read %f\n", d);
}
double value;
double *d = &value;
char newline;
char *c = &newline;
int val;
只要输入是浮点,上面的循环就会循环。一个问题是您不应该尝试扫描换行符。另一个问题是不相等运算符
=
的值高于赋值,这意味着val
是比较的结果。第三个错误是您没有提供一个指针来读取值(导致未定义的行为)
我建议这样改变:
while (scanf("%lf", &d) == 1)
{
printf("You have read %f\n", d);
}
double value;
double *d = &value;
char newline;
char *c = &newline;
int val;
只要输入是浮点,上面的循环就会循环。scanf()函数族是一个折磨性的测试,不应该对新手程序员进行测试。它们很难准确地使用
分析
即使忽略代码布局(完全令人震惊-这是一个专业评估),并假设您有如下变量声明:
while (scanf("%lf", &d) == 1)
{
printf("You have read %f\n", d);
}
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
),或0
,或1
或2
,其中只有2
是您要寻找的答案。因此,循环条件应为:
while ((val = fscanf(stdin, "%lf%c", d, c)) == 2)
while ((val = fscanf(stdin, "%lf%c", &d, &c)) == 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);
}
循环之后,您可以测试val==EOF
vsval==0
vsval==1
。第一个表示您已达到EOF或发生错误;第二个字符意味着输入中的下一个字符既不是空白,也不是有效数字的一部分(例如,字母或标点符号,而不是
,+
,-
)。val==1
案例是深奥的;它要求文件的结尾出现在后面没有换行符(或任何其他字符)的数字之后
无限循环
顺便说一句,造成无限循环的最可能原因是输入中的无效(非数字、非空白)字符。仔细观察,我发现在第二行输入上有一个r
;这将触发代码的无限循环fscanf()
将始终返回0,这不是EOF,因此循环将继续。(它不能用%c
读取r
,因为它必须先成功读取一个数字。)
合成
%lf
格式将跳过任何前导空格,包括换行符,因此您的代码试图确保每行有一个数字,并且没有尾随空格。在这种情况下,您可能会更好地使用fgets()
,尽管完全正确地使用strod()
并不是一件小事。下面的代码忽略了strod()
的细节
fgets()
返回空指针的唯一原因是您已达到EOF或发生错误。您可能需要设置errno=0调用strtod()
之前进行编码,然后检查其值以找出超出范围的数字。函数族是一种折磨性的测试,不应该对新手程序员进行测试。它们很难准确地使用
分析
即使忽略代码布局(完全令人震惊-这是一个专业评估),并假设您有如下变量声明:
while (scanf("%lf", &d) == 1)
{
printf("You have read %f\n", d);
}
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
),或0
,或1
或2
,其中只有2
是您要寻找的答案。因此,循环条件应为:
while ((val = fscanf(stdin, "%lf%c", d, c)) == 2)
while ((val = fscanf(stdin, "%lf%c", &d, &c)) == 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
不是换行符,则是错误的,因此实际上它应该是