为啥这个 Scanf 会导致无限循环?
Posted
技术标签:
【中文标题】为啥这个 Scanf 会导致无限循环?【英文标题】:Why Does This Scanf Result in Infinite Loop?为什么这个 Scanf 会导致无限循环? 【发布时间】:2012-09-27 20:23:44 【问题描述】:所以我刚刚开始为我的一个班级学习 C,我一直在做这个作业,但这部分让我感到困惑。我有一些基本上看起来像这样的代码:
#include <stdio.h>
#include <string.h>
int main(void)
int one = 0;
int two = 0;
char oneWord[100];
char twoWord[100];
printf("Enter a two digit number: ");
scanf("%d%d", &one, &two);
strcpy(firstWord, "Test");
strcpy(secondWord, "Two");
printf("%s", firstWord);
return 0;
现在,撇开程序的逻辑/目的不谈,我无法弄清楚为什么该 scanf 语句会导致无限循环?当我将其注释掉并且最终的printf
语句运行良好时,我确定这就是问题的原因。
我尝试将其更改为 scanf("%d,%d", %one, %two)
,当我在输入中添加逗号时,这似乎工作正常。但我希望能够取一个像 55 这样的数字并将其分成 2 位数字。我到底做错了什么?
【问题讨论】:
抱歉,我没有阅读完整的故事。将%d
更改为%c
以仅读取一个字符
大声笑,在发布问题后才发现这一点。就我而言,有效的是scanf("%1d%1d", &one, &two)
。
输入的数字用空格隔开怎么样?
【参考方案1】:
我可能错了,但%d
的意思是“一个整数”,而不是“一个数字”。所以55
是第一个%d
,然后第二个没有定义。
您可以尝试使用%c
(一个字符)。
【讨论】:
你可能是对的。请参阅this 以供参考,但并未完全回答他的问题。 还告诉他不是死循环。相反,它正在等待再输入一个数字。 更准确地说,“d”代表“十进制”,意思是“十进制数”,也就是以10为底的数字。【参考方案2】:printf("Enter a two digit number: ");
scanf("%1d%1d", &one, &two);
当然,即使这样也可能失败(不符合要求) 而是:
scanf("%d", &one);
if (one<10 || one>99) printf("I didn't expect that...\n");
或
scanf("%s",oneWord); one = atoi(oneWord);
if (one<10 || one>99)
printf("Thats not necessarily even a number\n");
else
two = one % 10; one = one / 10;
printf("The first digit is %d and the second is %d\n",one,two);
在后一个程序中,我们正在测试输入是否正确: 喂垃圾而不是正确的输入是一个很好的做法,看看它在哪里被忽视了。库函数 atoi(string);返回包含在字符串中的整数。如果没有找到整数,则为零。例如(atoi("a1") == 0).
但最低正确答案是
scanf("%d", number);
if (number >= 10 && number <= 99)
one = number / 10; // the first digit;
two = number % 10; // the second digit calculated as number modulo 10
scanf("%1d%d", &one, &two); // would halt for a single character input
【讨论】:
如果one
是单个十进制(如“d”)数字,那么它怎么可能大于9?并且本身不确定其作用的错误检查不是有效的错误检查。
尝试第一个示例并输入例如123;这不是一个两位数的数字。
我错过了您没有在第二个格式字符串中使用宽度说明符(与第一个格式字符串不同)。但是,它不能解决提问者将数字字符串分解为多个数字的问题。另外:您的第二个示例对于手头的问题来说有点过分了。也许至少解释一下你在那里做什么?【参考方案3】:
您遇到的不是无限循环,而是scanf
等待更多输入。
d
-format-specifier 表示十进制数,因此可以是“0”、“41”或“2342345”。
输入第一个数字后,你希望程序继续,但scanf
刚刚完成第一个%d
,所以scanf
正在等待你完成第二个%d
。这在您看来是一个无限循环,但实际上scanf
正在按照您的要求行事。
scanf
无法猜测您想要的每个数字的位数。但是你可以告诉它你想要的方式,用一个宽度说明符来说明每个信息由多少个字符组成:
#include <stdio.h>
int main ()
int a, b;
scanf("%2d%1d", &a, &b);
printf("%d, %d", a, b);
带有错误处理:
#include <stdio.h>
int main ()
int a, b;
if (scanf("%2d%1d", &a, &b) < 2)
fprintf(stderr, "not enough digits");
else
printf("%d, %d", a, b);
【讨论】:
还告诉他不是死循环。相反,它正在等待再输入一个数字。 天啊,没想到这么快就有这么多答案!但我最终做的是scanf("%1d%1d", &one, &two)
,与您的scanf("%2d%1d", &one, &two)
解决方案相比,这样做有什么问题吗?
@This0nePr0grammer:你必须明白d
前面的数字是什么意思:它是要解析的位数,所以对于“%3d”和数字“123456”,scanf
会给你“123”。现在您应该可以自己回答问题了。
@phresnel 啊,有道理。非常感谢! :)
@This0nePr0grammer 欢迎 :) (编辑:为“无限循环”添加了更详细的解释)以上是关于为啥这个 Scanf 会导致无限循环?的主要内容,如果未能解决你的问题,请参考以下文章