检查C中的输入类型

时间:2017-06-04 14:49:57

标签: c casting type-conversion

我想检查输入是否是整数(例如,不是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;
}

有人可以解释一下它的工作原理吗?

4 个答案:

答案 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字符串intfloat等。相反,最好将它们视为阅读 text 并将它们转换为 C字符串intfloat

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 
    ....
}