使用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的返回值:)