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

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

代码:

#include  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无法解析您的输入。 由于您使用了%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()让人很困惑……

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

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

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

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

来自Linux手册页

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

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

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

重点是我的。 所以@oli charlesworth说如果有疑问你应该检查scanf的返回值:)