我想检查输入是否是整数(例如,不是char或字符串)。 我偶然发现了这段代码(有效):
#include <stdio.h>
int main (void)
{
float a;
int q;
printf("\nInsert number\t");
scanf("%f",&a);
q=(int)a;
++q;
if((q - a) != 1)
printf("\nThe number is not an integer\n\n");
else
printf("\nThe number is an integer\n\n");
return 0;
}
有人可以解释一下它的工作原理吗?
答案 0 :(得分:2)
我偶然发现了这段代码(有效):...为什么会这样?
一般来说,它不起作用。太多失败的案例
鉴于输入可能是单个字符Z
,以下代码是未定义的行为(UB),因为scanf()
未分配a
。结果:(int)a
是UB。
scanf("%f",&a);
q=(int)a;
鉴于输入可能是&#34; 12345678901234567890&#34;,超出int
范围的内容,然后使用(int)a
进行转换也是UB。
如果a
取值为INT_MAX
,则++q;
为UB。
输入可以精确表示为int
但不能作为float
失败的OP代码的值。
四舍五入为"0.99999999999999999999999999999"
的整数 - &gt;的输入1.0f
无法通过OP检测
替代。
scanf(), fgets()
请勿阅读 C字符串,int
,float
等。相反,最好将它们视为阅读 text 并将它们转换为 C字符串,int
,float
。
f
中的scanf()
暗示格式化输入,这是未知部分。最好避免scanf()
。
由于代码需要检测有关用户输入的各种内容,因此请使用fgets()
来读取文本的行。然后使用strtol()
,strtoll()
,strtoul()
等查看输入是否适合目标类型。
// Check if input fits in a `long`
char buf[100];
if (fgets(buf, sizeof buf, stdin) == NULL) {
puts("End-of-file or input error");
} else {
char *endptr;
errno = 0;
long ivalue = strtol(buf, &endptr, 0);
if (buf == endptr) puts("Fail: no conversion");
else if (*endptr != '\n' && *endptr != '\0') puts("Fail: Extra junk");
else if (errno) puts("Fail: Overlfow");
else printf("Success: %ld\n", ivalue);
}
答案 1 :(得分:1)
代码本身非常简单,我们正在将float
转换为int
,然后增加int
值:
q=(int)a;
++q;
然后,每次提供int
作为输入时,(q-a)
的结果都将是1
。但是,提供的输入(并保存到float a
)的类型为float
,结果将大于1
(对于正数)。
这是因为在(q-a)
中,q
将转换为float
,其结果也将为float
。
请参阅the C book:
的示例否则,如果任一操作数是浮点数,那么另一个操作数是 转换为float,这就是结果的类型。
答案 2 :(得分:1)
你输入a
这是一个浮点数。然后,您将float
投放到int
整数q
并增加1 (q++)
。因此,如果你输入a = 3.4
q=(int)a;
++q;
然后q
将是4
。但它无法改变a
的价值。因此a
将是3.4
。
检查此条件后(q - a) != 1
将为真,否则为假。
最后,如果您输入a=3.0
,则此代码将无效。(因为a=3.0
是一个浮点数。)
答案 3 :(得分:1)
这句话:
scanf("%f",&a);
可以告诉你你想知道什么。
调用scanf()系列函数时:始终检查返回值(而不是参数值)以确保操作成功。
在这种情况下建议:
if( 1 != scanf("%f",&a) )
{ // non digit entered
....
}