相关疑难解决方法(0)

可以`unsigned int x; scanf("%u",&x);` 真的会导致未定义的行为吗?

有一次我认为我发现了sscanf() 的一个很好的用途,但在阅读了它如何处理整数之后,它似乎不是。有一个应该看起来像这样的字符串:123,456,678我想我可以使用以下代码安全简洁地解析它:

unsigned int x[3];
if( sscanf( s, "%u,%u,%u", x+0, x+1, x+2 ) == 3 )
    …
Run Code Online (Sandbox Code Playgroud)

如果转换失败,我对知道原因并不真正感兴趣,也不担心获得不正确的数据。如果那里有数字以外的东西,scanf()肯定应该创建一个匹配错误并中止,并且它知道我正在寻找一个无符号整数,所以任何负数也应该是一个匹配错误?不。

当我读到转换说明符%u时,我开始怀疑:匹配一个可选的有符号十进制整数。为什么这不是匹配错误?如果签了会怎样?

引自 ISO/IEC 9899:201x 7.21.6.2 ¶ 10,fscanf 函数(重点是我的):

除了 % 说明符的情况外,输入项(或者,在 %n 指令的情况下,输入字符的计数)被转换为适合转换说明符的类型。如果输入项不是匹配序列,则指令执行失败:这种情况是匹配失败。除非赋值抑制由 * 指示,否则转换结果将放置在尚未收到转换结果的格式参数之后的第一个参数所指向的对象中。如果此对象没有合适的类型,或者转换的结果无法在对象中表示,则行为是 undefined

它看起来好像scanf()将每个看起来像整数的转换说明符都视为相同,将输入读取为某种未指定大小的有符号整数,然后绕过所有正常转换写入输出。

例如,根据正常的隐式转换,将任何整数(负数或正数)转换为较小大小的无符号整数表现良好,但不适用于scanf()

unsigned int x;
x = -1;                   /* Well defined: (-1) + (UINT_MAX+1) = UINT_MAX */
sscanf( "-1", "%u", &x ); …
Run Code Online (Sandbox Code Playgroud)

c scanf integer-overflow language-lawyer

5
推荐指数
1
解决办法
130
查看次数

标签 统计

c ×1

integer-overflow ×1

language-lawyer ×1

scanf ×1