【问题标题】:Behaviour of printf using length subspecifier with a string使用带有字符串的长度子说明符的 printf 的行为
【发布时间】:2016-11-14 18:54:10
【问题描述】:

我很好奇 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 但与所有其他长度修饰符一起它似乎忽略了长度修饰符并像正常用法一样工作)。

为什么它遵循这种行为?

【问题讨论】:

    标签: c printf undefined-behavior libc format-specifiers


    【解决方案1】:

    答案是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");
    

    【讨论】:

    • "... 不支持任何长度修饰符..." - %ls 不是指宽字符串吗?
    • "...你已经使用了你传递的参数。"。 %ls 不是表示宽字符串吗?” - 是的。
    【解决方案2】:

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

    hhhlljzt 均未定义为与 s 一起使用。

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

    【讨论】:

      猜你喜欢
      • 2013-10-09
      • 1970-01-01
      • 1970-01-01
      • 2014-01-07
      • 1970-01-01
      • 1970-01-01
      • 2018-07-19
      • 2011-11-18
      • 1970-01-01
      相关资源
      最近更新 更多