无限循环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
vs
val==0
vs
val==1
。第一个表示您已达到EOF或发生错误;第二个字符意味着输入中的下一个字符既不是空白,也不是有效数字的一部分(例如,字母或标点符号,而不是
+
-
)。
val==1
案例是深奥的;它要求文件的结尾出现在后面没有换行符(或任何其他字符)的数字之后

无限循环 顺便说一句,造成无限循环的最可能原因是输入中的无效(非数字、非空白)字符。仔细观察,我发现在第二行输入上有一个
r
;这将触发代码的无限循环
fscanf()
将始终返回0,这不是EOF,因此循环将继续。(它不能用
%c
读取
r
,因为它必须先成功读取一个数字。)

合成
%lf
格式将跳过任何前导空格,包括换行符,因此您的代码试图确保每行有一个数字,并且没有尾随空格。在这种情况下,您可能会更好地使用
fgets()
,尽管完全正确地使用
strod()
并不是一件小事。下面的代码忽略了
strod()
的细节

fgets()
返回空指针的唯一原因是您已达到EOF或发生错误。您可能需要设置
errno=0strtod()
之前进行编码,然后检查其值以找出超出范围的数字。

函数族是一种折磨性的测试,不应该对新手程序员进行测试。它们很难准确地使用

分析 即使忽略代码布局(完全令人震惊-这是一个专业评估),并假设您有如下变量声明:

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
不是换行符,则是错误的,因此实际上它应该是