使用带字符串的长度子说明符的 printf 行为

Behaviour of printf using length subspecifier with a string

我很好奇 printf 是如何工作的,我尝试了很多技巧,例如:

printf("Test 1: %hs\n", "hi");
printf("Test 2: %hhs\n", "hi");
printf("Test 3: %ls\n", "hi");
printf("Test 4: %lls\n", "hi");
printf("Test 5: %js\n", "hi");
printf("Test 6: %zs\n", "hi");
printf("Test 7: %ts", "hi");

我正在使用带有 s 说明符和所有长度修饰符的 printf(通常与数字说明符一起使用(如 d / i / u / o ...),我得到了奇怪的输出:

Test 1: hi
Test 2: hi
Test 3: Test 4: Test 5: Test 6: hi
Test 7: hi

似乎是 l / ll / j 长度修饰符导致 printf 错误并停止工作(它不打印 \n 但对于所有其他长度修饰符,它似乎忽略了长度修饰符并工作像正常使用一样)。

为什么会出现这种行为?

答案是undefined behaviour。格式说明符 %s 不支持您用于传递的参数的任何长度修饰符。格式说明符不匹配在 C 中未定义。当我使用 gcc 编译器 (gcc -Wall -Wextra -std=c11 test.c) 编译您的代码时,它表示:

test.c: In function ‘main’:
test.c:5:19: warning: use of ‘h’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=]
 printf("Test 1: %hs\n", "hi");
                   ^
test.c:6:20: warning: use of ‘hh’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=]
 printf("Test 2: %hhs\n", "hi");
                    ^
test.c:7:19: warning: format ‘%ls’ expects argument of type ‘wchar_t *’, but argument 2 has type ‘char *’ [-Wformat=]
 printf("Test 3: %ls\n", "hi");
                   ^
test.c:8:20: warning: use of ‘ll’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=]
 printf("Test 4: %lls\n", "hi");
                    ^
test.c:9:19: warning: use of ‘j’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=]
 printf("Test 5: %js\n", "hi");
                   ^
test.c:10:19: warning: use of ‘z’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=]
 printf("Test 6: %zs\n", "hi");
                   ^
test.c:11:19: warning: use of ‘t’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=]
 printf("Test 7: %ts", "hi");

唯一可以与 %s 一起使用的有效长度修饰符是 l,它表示参数的类型为 wchar_t,而不是 char

hhhlljzt 中的

None 定义为与 s 一起使用。

请参阅 C 2011 online standard,§7.21.6.1,第 7 段。