是否禁止 C scanf() 检查整数是否在范围内?

问题描述 投票:0回答:3

我今天了解到 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)上,上面的程序会说“returned 1”,意思是

scanf()
读取指定的标记,即使输入是不可表示的,例如
4223215425243525443245234453
man scanf
说:

当输入的字符与格式字符不匹配时,扫描停止。当无法进行输入转换时,扫描也会停止。

C 标准 require 这种行为,还是允许

scanf()
的实现者将超出范围的数字输入视为无效(因此在上述情况下返回 0)?如果需要这种行为,我将不胜感激引用标准说法。

c language-lawyer scanf integer-overflow
3个回答
6
投票

如果这个对象没有合适的类型,或者如果转换的结果不能在对象中表示,则行为是 undefined.

所以绝对允许任何事情。


5
投票

C11 7.21.6.2 fscanf函数/10,我们看到:

如果这个对象没有合适的类型,或者如果 转换不能在对象中表示,行为是 未定义。


0
投票

“C scanf() prohibited 检查整数是否在范围内?”

根据 linux scanf 手册页@https://linux.die.net/man/3/scanf,没有禁止:

Return Value

These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.  
[...] and errno is set indicate the error. 

[...]  

ERANGE

The result of an integer conversion would exceed the size that can be stored in the corresponding integer type. 

Conforming To

The functions fscanf(), scanf(), and sscanf() conform to C89 and C99 and POSIX.1-2001. These standards do not specify the ERANGE error. 

(A) 看起来“标准”声明这是未定义的行为,glibc 正在做一些调整以检查范围。

(B) scanf 函数需要一个 const 格式,其他所有内容都不会被“检查”以确保完整性,例如确保指针已被分配并且有足够的大小来保存输入并匹配给定的转换等。在那个场景中, 检查范围也安全不了多少

int scanf(const char *format, ...);
© www.soinside.com 2019 - 2024. All rights reserved.