我已经知道,返回的scanf
值表明它是否能够成功读取和转换值。
我使用返回值来检测输入是否为整数,但是输入是否为4.5
scanf
返回1,而输入为g
scanf
返回0 。
她是我的密码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x;
int ReturnedValue=scanf("%d",&x);
printf("Scanf Returned:%d",ReturnedValue);
return 0;
}
在多篇不同的文章中,您建议使用返回的scanf
值来检测整数,但是为什么现在不起作用?
答案 0 :(得分:5)
返回值不表示成功或失败。这是成功转换的值的数量。
这就是为什么您以"%d"
为格式在“ 4.5”上获得“ 1”,然后将“ 4”转换为
通过阅读scanf()
的文档,您会发现这一点。
答案 1 :(得分:3)
问题是scanf
(或atoi
)解析整数并不可靠。
在您的情况下,scanf
找到4
并对此感到满意,这说明了返回码1。
最安全的方法是使用strtol
,strtoul
..基元,以确保 word 作为整数有效(有关更多详细信息,请检查{{3 }},答案是“不要使用scanf
”顺便说一句:))
在您的特定情况下(粘在scanf
上,您可以可以通过先扫描为 float (使用%f
浮动变量)。并检查浮点值是否为整数。
float xf;
if (scanf("%f",&xf) == 1)
{
// one integer or float was scanned
x = (int)xf;
if (x==xf)
{
// scanned value is an integer: valid
}
}
但是4XXXX
之类的输入仍然会被错误地接受。如果您必须使用scanf
,则必须承担一定程度的风险。
答案 2 :(得分:0)
我已经使用返回值来检测输入是否为整数,但是如果输入为4.5,则scanf返回1,如果输入为g,则scanf返回0。
在这种情况下,这实际上是有道理的。
int ReturnedValue = scanf(“%d”,&x);
记住scanf
返回值是正确解析的项目数。
如果输入4.5,它将仅读取第一个数字4并正确解释int
值。它将丢弃输入中所有剩余的无效字符。
如果输入d
,则scanf完全失败(它无法解析任何int),因此返回0。
请参阅scanf手册-了解为什么将4.5解析为整数4:
在达到此最大值时,字符的读取将停止 已到达或找到不匹配的字符 首先发生。
答案 3 :(得分:0)
最初,我不想写答案,只留下评论。我想要 扩展Jean-François Fabre的答案。
scanf
家庭的问题在于他们没有做大多数人做的事
相信他们这样做,然后就为何这样做“奇怪”感到困惑。实际上,他们根据格式扫描输入并为
变量(通过指针传递)。当他们遇到错误时,即某事
与格式不匹配,然后它们停止。
使用"%d"
格式,您只是说要读一个整数。格式不
说“读一个整数,只有一个整数”。为此,您还需要
排除其他所有内容,如果我没有记错的话,那将是
"%d[^0-9]*"
(我没有测试过是否正确)。
这就是为什么用户输入4.5
被
scanf
。请注意,scanf
的操作不正确,是您在指定它
错误地,因为您假设"%d"
的意思是“以及整数和整数
唯一”。
如您所见,很难找到一种可以捕捉的格式 一切,还告诉您用户何时出错。用户输入又名什么 用户输入的内容是随机的,可能包含(无意间)错误,请 格式等。因此,您最终会得到非常复杂的格式,只能确定 用户在末尾添加了一个点,如果这样做则失败。
这就是为什么我的建议是通过fgets
阅读while输入,然后使用更好的东西
如果格式良好,则可以解析strtol
甚至sscanf
之类的输入。
以下是strtol
用法的示例:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *entries[] = { "4.5", "4", "some random text" };
char *ptr;
int i;
for(i = 0; i < sizeof entries / sizeof *entries; ++i)
{
long int res = strtol(entries[i], &ptr, 0);
if(*ptr != '\0') {
printf("The input '%s' is not an integer. The non-integer is '%s'\n", entries[i], ptr);
} else {
printf("The input '%s' is an integer: %ld\n", entries[i], res);
}
}
return 0;
}
返回
The input '4.5' is not an integer. The non-integer is '.5'
The input '4' is an integer: 4
The input 'some random text' is not an integer. The non-integer is 'some random text'
这是检查整个输入是否为整数的更精确的方法。
答案 4 :(得分:0)
发生错误时,Scanf返回1而不是0
输入中未发生错误。第一个字符"4"
可以很好地转换为4
。代码需要检查其余部分。
我被迫在拼贴中使用scanf
不幸的是,这种编码约束。 fgets()/strtol()
会更好。
如何在不破坏c整个代码的情况下,以简单快速的方式检测它是否为整数?
扫描整数并查找结尾的垃圾。
char endchar;
int cnt = scanf("%d%c",&x, &endchar);
if (cnt == EOF) puts("End-of-file occurred");
else if (cnt == 1 || (cnt == 2 && endchar == '\n')) printf("Success %d\n", x);
else puts("Non-integer input");
当数据为非整数输入时,stdin
中可能会保留一些有问题的字符。因为此任务只是读取一个int
,所以可以。
生产代码更有可能读取行然后对其进行解析。