繁体   English   中英

使用scanf输入字符并将其保存为int会导致未定义的行为?

[英]entering a char using scanf and saving it in an int can cause undefined behaviour?

我正在编写代码,尝试输入一个char而不是整数,无论​​输入的字符如何,结果均为'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,..... ,结果是相同的。 那是什么?

如果scanf()遇到无法根据指定的格式字符串进行解析的内容,它只会停止并提早返回。 因此,它永远不会向t写入任何内容(您只是看到在调用之前t具有任何不确定的值)。

要处理此问题,您应该始终检查scanf返回值。

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

您需要检查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);
}

这是因为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()

Linux手册页

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

在scanf( 7.21.6.4 scanf函数 )的C11标准描述中:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM