0

我正在编写代码,我尝试输入一个字符而不是整数,结果是“2”,不管我输入的字符是什么,是未定义的行为还是其他什么?

编码:

#include <stdio.h>
int f1(int n);
int f2(void);

int main(void)
{
    int t;

    printf("Enter a number: ");
    scanf("%d", &t);
    /* print proper message */
    t ? f1(t) + f2() : printf("zero entered.\n");
    return 0;
}

int f1(int n)
{
    printf("%d ", n);
    return 0;
}

int f2(void)
{
    printf("entered.\n");
    return 0;
}

当我输入时a,结果是“2输入”,当我输入时g结果是“2输入”,当我输入时i,h,k,.....结果是一样的。那是什么?

4

5 回答 5

3

如果scanf()遇到无法根据指定格式字符串解析的内容,它会简单地停止并提前返回。所以它从不写任何东西t(你只是t在调用之前看到任何不确定的值)。

要处理这个问题,您应该始终检查.scanf

于 2013-08-18T09:30:36.657 回答
0

问题是,正如您所说,使用 %d 格式的 scanf 期望您输入一个或多个 ascii 数字。它停止在非数字字符处扫描输入,因此它永远不会读取您键入的内容,并且 t 具有调用 scant 之前的任何值。

于 2013-08-18T09:31:09.003 回答
0

您需要检查scanf. 看看手册页

返回值

这些函数返回成功匹配和分配的输入项的数量,该数量可能少于提供的数量,或者在早期匹配失败的情况下甚至为零。

如果在第一次成功转换或匹配失败发生之前到达输入结尾,则返回值 EOF。如果发生读取错误,也会返回 EOF,在这种情况下会设置流的错误指示符(请参阅 ferror(3)),并设置 errno 来指示错误。

换句话说,scanf不向 写入任何内容t,它一直未初始化。

所以,而不是这个:

scanf("%d", &t);

尝试这个:

int items_matched = scanf("%d", &t);
if (items_matched != 1) {
    printf("bad number entered\n");
    exit(1);
}
于 2013-08-18T09:31:09.503 回答
0

这是因为scanf无法解析您的输入。它希望您输入十进制数字,因为您使用了%d.

您必须检查 的返回值scanf以避免这种行为:

成功时,该函数返回参数列表中成功填充的项目数。由于匹配失败、读取错误或到达文件结尾,此计数可以与预期的项目数匹配或更少(甚至为零)。

所以 :

int items_matched;

// ...
items_matched = scanf("%d", &t);   // Get the return value

if ( items_matched != 1 )          // Check it
{
    printf("Matching failure with scanf.\n");
    return 0;
}
else
{
    if ( t == 0 )
        printf("zero entered\n");
    else
        printf("%d entered\n", t);
}

你不需要你的f1(t) + f2()人很混乱......

于 2013-08-18T09:40:38.067 回答
0

来自Linux 手册页

格式字符串由一系列指令组成,这些指令描述了如何处理输入字符序列。如果指令处理失败,则不再读取任何输入,并且 scanf() 返回。“失败”可以是以下任何一种:输入失败,意味着输入字符不可用,或匹配失败,意味着输入不合适。

在scanf的C11标准描述(7.21.6.4 scanf函数)第3节:

如果在第一次转换(如果有)完成之前发生输入故障,scanf 函数将返回宏 EOF 的值。否则,scanf 函数返回分配的输入项的数量,如果发生早期匹配失败,该数量可能少于提供的数量,甚至为零

重点是我的。因此,正如@oli charlesworth 所说,您应该在有疑问时检查 scanf 的返回值:)

于 2013-08-18T12:11:48.650 回答