2017-06-04 69 views
1

我想检查我的输入是否是整数(例如,不是字符或字符串)。检查C中的输入类型

#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; 
} 

是否有人可以解释为什么它的工作原理: 我碰到这个代码(即作品)偶然?

+3

该代码是不可能的,如果你输入987654321作为价值的工作。如果您输入ABC,则更不可能工作。 –

+0

这段代码与输入是“char”还是“string”无关。 –

+1

*总是*测试'scanf'的返回值,这里应该是'1'。如果你想输入一个'int',那么这样做,检查1值是否被转换,并检查输入流中的下一个“char”是否为空格。 –

回答

1

本身是相当简单的,我们正在改变铸造floatint然后该代码递增int值:

q=(int)a; 
++q; 

然后,每次有作为输入提供的int,的(q-a)结果将是正好是1。但是,它提供的输入(并保存到float a)类型为float,结果将大于1(对于正数)。

这是因为在(q-a),q将被转换为float,其结果也将是float

参见例如用于the C book

否则,如果操作数是浮点数,则另一个是 转化为浮动,那就是结果的类型。

+2

[如果要转换的值超出可以表示的值的范围,则行为未定义。](http://port70.net/~nsz/c/c11/n1570.html#6.3.1.4p2)它'float's可以保存不能用int表示的值。 –

+0

我不建议在任何地方使用此代码,问题是它是如何工作的,只是解释它。 – syntagma

+0

同意不推荐。只是认为UB是这个代码的一个重要特征(同样,如果用户输入了UB,例如一个字符串),因此评论。 –

1

你把输入a这是一个浮点数。然后,您将float转换为int整数q和增量1 (q++)。所以,如果你需要输入a = 3.4

q=(int)a; ++q;

然后q将是4。但它不能改变a的值。所以a将是3.4。 检查此条件后(q - a) != 1将为true,否则为false。

最后,如果你需要输入a=3.0那么这段代码将无法正常工作(如a=3.0是一个浮点数)。

2

我碰到这个代码(即作品)跌跌撞撞:......为什么它的工作原理?

它不起作用,一般来说。太多的失败案例

给定的输入可以是单个字符Z,后续代码未定义行为(UB)作为scanf()不分配a。结果:(int)a是UB。

scanf("%f",&a); 
q=(int)a; 

给定的输入可能是“123456789”,东西的int的范围之外,然后用(int)a转换也UB。

如果a取值为INT_MAX,++q;为UB。

输入值可以精确地表示为int而不是float失败OP的代码。被四舍五入到整数像"0.99999999999999999999999999999"

输入 - >1.0f失败OP的检测


替代。

scanf(), fgets()不读C字符串intfloat等取而代之的是,更好地把它们当作阅读文本并将它们转换为C字符串intfloat

f in 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

这样的说法:

scanf("%f",&a); 

可以告诉你,你想知道什么。

调用scanf()系列函数时:始终检查返回值(不是参数值)以确保操作成功。

在这种情况下建议:

if(1 != scanf("%f",&a)) 
{ // non digit entered 
    .... 
}