如果我忘记关闭扫描集会怎样?

What happens if I forget to close a scanset?

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

示例:

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 returns 1. 但是这里到底发生了什么?

我查了C11标准,没找到相关资料。

太棒了!您应该为 C11 提交缺陷报告!

这是C11 7.21.6.2中的相关部分

... The conversion specifier includes all subsequent characters in the format string, up to and including the matching right bracket (]). The characters between the brackets (the scanlist) compose the scanset, unless the character after the left bracket is a circumflex (^), in which case the scanset contains all characters that do not appear in the scanlist between the circumflex and the right bracket.

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