C语言scanf是否需检查整数范围?C标准对该行为有何规定?
关于scanf()处理超范围整数输入的标准规定
我了解到C语言的scanf()不会检查输入的整数是否可被指定类型表示,示例代码如下:
#include <stdio.h> int main(void) { short num; int ret = scanf("%hd", &num); printf("read %d, returned %d\n", num, ret); return 0; }
在Clang/MacOS系统中,即使输入如4223215425243525443245234453这类超出short范围的数值,程序仍会输出"returned 1",说明scanf()已读取该输入。man scanf中提到:
当输入字符与格式字符不匹配,或无法完成输入转换时,扫描停止。
请问:C标准是否强制要求上述行为?还是scanf()的实现者可将超范围的数值输入视为无效(并在上述场景返回0)?若该行为是强制要求的,希望能提供标准中的相关引用。
回答
C标准没有强制要求scanf()必须返回1或者将超范围输入视为无效,这种场景下的行为属于未定义行为,实现可以自行选择处理方式。
根据C17标准(ISO/IEC 9899:2018)的7.21.6.2节(fscanf函数,scanf是fscanf针对标准输入的封装)第10段规定:
如果输入项是可被解释为指定类型值的字符序列,则执行转换。如果转换结果无法在目标对象中表示,行为是未定义的。
这意味着:
- 当输入的数值超出目标类型(比如
short)的范围时,scanf()的行为没有统一标准约束 - 实现既可以像Clang那样返回1(表示成功读取输入,但目标变量的值是不确定的),也可以将这种情况视为转换失败,返回0,甚至触发其他异常行为
- 你看到的
man scanf描述只涵盖了"无法完成输入转换"的常规情况,但超范围数值的转换不属于这类明确的"无法完成转换"场景,而是落入未定义行为的范畴
内容的提问来源于stack exchange,提问作者John Zwinck
相关产品推荐
相关产品推荐

