【问题标题】:Why does %c format specifier not work in the following code? [closed]为什么 %c 格式说明符在以下代码中不起作用? [关闭]
【发布时间】:2021-03-17 06:38:55
【问题描述】:

我刚刚开始阅读有关 C 的内容,目前正在使用格式说明符。 下面是代码示例:

#include <stdio.h>


int main(void) {
    char code = 'a' - 'A';
    printf("\n>>>%c (%d)", code, code);
    printf("\n>>>%c", 32);

    char incode;
    printf("\n\nGive me some char: ");
    scanf("%c", &incode);
    printf("\n>>>%c (%d)", incode, incode);
    return 0;
}

输出:

PS C:\ex> ./print

>>>  (32)
>>>

Give me some char: A

>>>A (65)

那么,为什么 %c 在最后一个 printf 中起作用,而在开头却不起作用? 我在 Windows 和 Linux 上测试了这个示例,两者的行为相同。

  • Windows 编译器:gcc.exe (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0
  • Linux 编译器:clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)

【问题讨论】:

  • 为什么您认为第一个printf 不起作用?您的预期输出是什么?
  • 两个样本都在工作,'a' - 'A' 返回 32(空格字符),这就是打印的内容。
  • 是什么让您认为它不起作用?你期待什么?

标签: c printf clang


【解决方案1】:

ASCII 32 是' '(空格)。打印好了,就是看不到。
如果您将格式字符串更改为"\n&gt;&gt;&gt;%c&lt;&lt; (%d)",您将在(双关)负号空格中看到它。
您也可以将输出通过od -a 进行确认。

【讨论】:

  • 我喜欢你的回答。我只是没有得到“负空间”的东西。你能解释一下吗?
  • 感谢您的编辑。答案是“空间”是文字游戏(双关语),这个词也出现在艺术术语“负空间”中,维基百科将其定义为“负空间可能在主题周围的空间而不是主题本身时最明显,形成有趣或艺术相关的形状,”en.wikipedia.org/wiki/Negative_space
  • 有趣,感谢您的澄清。
【解决方案2】:

假设您的字符编码是ASCII。然后a 编码为 97(十进制),A 编码为 65(十进制)。它们的区别是 32,它编码了 空格字符。

所以char code = 'a' - 'A';char code = 32; 相同,与声明char code = ' '; 相同

另请参阅this C reference 网站。

如果允许,使用所有警告和调试信息进行编译,因此(使用GCC)为gcc -Wall -Wextra -g

您可以使用gcc -Wall -O -fverbose-asm minerals.c -S -o minerals.s 编译您的C 源代码minerals.c,并查看生成的汇编代码foo.s 的内部。在装有 GCC 10.2 的 Debian 计算机上,我收到以下警告:

minerals.c: In function ‘main’:
minerals.c:11:5: warning: ignoring return value of ‘scanf’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
   11 |     scanf("%c", &incode);
      |     ^~~~~~~~~~~~~~~~~~~~

生成的汇编代码有:

 # /usr/include/x86_64-linux-gnu/bits/stdio2.h:107:   return __printf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ());
         movl    $32, %ecx       #,
         movl    $32, %edx       #,
         leaq    .LC0(%rip), %rsi        #,
         movl    $1, %edi        #,
         call    __printf_chk@PLT        #
         movl    $32, %edx       #,           // 32 is the space
         leaq    .LC1(%rip), %rsi        #,
         movl    $1, %edi        #,
         movl    $0, %eax        #,
         call    __printf_chk@PLT        #
         leaq    .LC2(%rip), %rsi        #,
         movl    $1, %edi        #,
         movl    $0, %eax        #,
         call    __printf_chk@PLT        #

实际上,在 2021 年,UTF-8 is used everywhere(并使事情复杂化)。查看GNU libunistring

【讨论】:

  • Nops,97 和 65 是它们各自的十进制值。
猜你喜欢
  • 2021-08-27
  • 2011-12-28
  • 2017-05-24
  • 1970-01-01
  • 1970-01-01
  • 2014-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多