【问题标题】:Printing a two digit number as character将两位数打印为字符
【发布时间】:2015-01-16 10:33:32
【问题描述】:

我有这行代码:

printf("%c\n", '65');

此代码将5 打印到控制台。

我知道65 不是有效字符,也没有分配任何ASCII 值,那么这个输出背后的原因是什么?

【问题讨论】:

  • @Gopi 哦!哪一个?
  • 但是65 分配给了一个有效的ASCII字符!我什至不必查找它;这是A
  • 事实证明它确实可以编译,但它大错特错,我很生气。为什么这会产生警告而不是错误? @Jongware 是 65 而不是 '65',请看我的回答。
  • @iharob:不,OP 是正确的,因为这仍然是有效的语法。但是,它是特定于实现的,因此报告的输出可能因编译器而异。
  • C 允许它作为实现定义的行为,但这并不意味着代码在任何编译器上都有意义。 GCC 似乎打印了文字中最右边的字符,这取决于 GCC 的实现。它与字节序无关。

标签: c printf character ascii


【解决方案1】:

单引号给出一个字符的ascii值,称为字符常量

printf("%c\n", '65');

multicharacter constant,这是实现定义的

65'A' 字符的 ascii 值,所以我想你的意思是

printf("%c\n", 'A');

相当于

printf("%c\n", 65);

使用多字符字符常量,由实现定义。例如gcc

编译器一次计算一个字符的多字符字符常量,将前一个值左移每个目标字符的位数,然后在截断到宽度的新字符的位模式中进行或运算的目标人物。最终的位模式被赋予 int 类型,因此是有符号的,无论单个字符是否有符号(与 GCC 3.1 和更早的版本略有不同)。如果常量中的字符多于目标 int 中的字符数,编译器会发出警告,并忽略多余的前导字符。

例如,对于具有 8 位字符的目标,'ab' 将被解释为“(int) ((unsigned char) 'a' * 256 + (unsigned char) 'b')”,而“\234a”将被解释为“(int) ((unsigned char) '\234' * 256 + (unsigned char) 'a')”。

Reference

所以在gcc 中你会得到5,因为

printf("%c\n", '65');

等价

printf("%c\n", (int)(((unsigned char)'6' * 256) | (unsigned char)'5'));

最后从你的问题的标题看来,你想要的

printf("%d\n", 65);

即打印十进制值65

【讨论】:

  • 第一句话说“没有多字符字符常量”,然后你继续引用例如GCC 实现它们?语言中的多字符字符常量,具有实现定义的实际值。
  • 在最后一个 printf 中的值应该是字符而不是整数,对吧?喜欢printf("%c\n", (int)(((unsigned char)'6' * 256) | (unsigned char)'5'));
  • 但是您之前的 printf 不会给出预期的结果,即 5 现在看起来不错 (+1)
【解决方案2】:

%c 只打印一个字符。 %s 打印一个字符串。

所以试试这个:

printf("%s\n", "65");

来源:http://www.cplusplus.com/reference/cstdio/printf/

编辑:如果 65 是一个字符的十进制数,那么写这个:

printf("%c\n", 65);

【讨论】:

  • 为什么 OP 会得到 reported 输出? (我当然知道——但这会改善你的答案。)
  • 这没有回答问题。
【解决方案3】:

我们知道 char 的大小是 8 位。在这里,您尝试使用 %c 打印 '65'。 %c 将寻找打印 8 位。 '65' 是 16 位: 6的ASCII值为54,二进制为00110110,5的ASCII值为00110101 所以问题是“%c 是要打印前 8 位还是后 8 位”。 嗯,这取决于你的系统是使用小端还是大端。 Big Endian 直截了当,将“54”存储为 00110110 00110101。但 Little Endian 先存储 LSB,然后存储 MSB,即 00110101 00110110。您的系统似乎支持 Little endian,因此 %c 采用前 8 位,即 00110101,即 5 .

【讨论】:

    【解决方案4】:
    &丢弃所有其他位。

    【讨论】:

      【解决方案5】:

      我必须像你一样分配两位数字作为字符。当我搜索打印两位数时,只有帖子是您的帖子。因此,我写在这里。

      我写了一个可能对每个人都有帮助的函数。

      void setElementID(char* name,int count){
          int len = strlen(name);
          char buffer[5];
          int n = sprintf(buffer,"%d",count);
          printf("%s",buffer);
          for(int i=0;i<n;i++){
               name[len] = buffer[i];
               len++;
          }
          name[len+n]='\0';
      }
      

      我认为这将解决您的问题。

      此函数将根据需要生成任意数量的客户端 ID。您只需持有 count 变量并在必要时增加它。

      如果您只想打印数字,您只需打开
      char numbers[10];
      并将其与您的计数器一起提供给此函数。

      我的参考资料:http://www.cplusplus.com/reference/cstdio/sprintf/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-12
        • 2022-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-20
        • 1970-01-01
        相关资源
        最近更新 更多