如果我忘记关闭扫描设置会发生什么?

时间:2016-01-30 13:49:04

标签: c scanf format-specifiers

假设我忘记关闭扫描集的右方括号]。那会发生什么?它是否会调用未定义的行为?

示例:

char str[] = "Hello! One Two Three";
char s1[50] = {0}, s2[50] = {0};
sscanf(str, "%s %[^h", s1, s2); /* UB? */
printf("s1='%s' s2='%s'\n", s1, s2);

编译时我收到GCC的警告:

source_file.c: In function ‘main’:
source_file.c:11:5: warning: no closing ‘]’ for ‘%[’ format [-Wformat=]
     sscanf(str, "%s %[^h", s1, s2); /* UB? */

,输出为

s1='Hello!' s2=''

我也注意到sscanf会返回1.但是到底发生了什么?

我已经检查了C11标准,但没有找到与此相关的信息。

1 个答案:

答案 0 :(得分:5)

出色!您应该为C11提交缺陷报告!

以下是C11 7.21.6.2中的相关部分

  

... 转换说明符包括格式字符串中的所有后续字符,包括匹配的右括号(])。括号(扫描列表)之间的字符组成扫描集,除非左括号后面的字符是抑扬符(^),在这种情况下,扫描集包含在旋转和右括号之间的扫描列表中不出现的所有字符。

的严格解释括号之间的字符是没有右括号时没有这样的字符,但是^作为[之后的第一个字符{1}},它会不一致。 gcc非常友好地指出了源代码中的可能错误。实际行为由C库实现确定,但似乎没有在C标准中指定。因此,这是一种未定义的行为形式,恕我直言应该在标准中如此记录。