【问题标题】:printf char as hex in cprintf char作为c中的十六进制
【发布时间】:2021-04-10 00:58:48
【问题描述】:

我希望从下面的代码中输出类似于\9b\d9\c0... 的内容,但我得到的是\ffffff9b\ffffffd9\ffffffc0\ffffff9d\53\ffffffa9\fffffff4\49\ffffffb0\ffff ffef\ffffffd9\ffffffaa\61\fffffff7\54\fffffffb。我向 char 添加了显式转换,但它没有效果。这是怎么回事?

typdef struct PT {
    // ... omitted
    char GUID[16];
} PT;
PT *pt;
// ... omitted
int i;
for(i=0;i<16;i++) {
    printf("\\%02x", (char) pt->GUID[i]);
}

编辑:只有投射到(unsigned char) 对我有用。编译器在使用 %02hhx (gcc -Wall) 时向我发出警告。 (unsigned int) 无效。

【问题讨论】:

  • 这不是%xunsigned int 当作论据吗?
  • 2 中的数字 %02 始终指定字段中的最小位数。 printf 将使用最小的实现类型,unsigned int 来打印值。这就是结果的原因。
  • 你为什么要添加一个明确的演员表char(你已经有了)?我认为(unsigned int) 会更符合您的需求。

标签: c printf


【解决方案1】:

发生这种情况的原因是您系统上的chars 已签名。当您将它们传递给具有可变数量参数的函数时,例如printf(在签名的固定参数部分之外)chars 被转换为int,并且它们在此过程中得到符号扩展。

要解决此问题,请将值转换为 unsigned char

printf("\\%02hhx", (unsigned char) pt->GUID[i]);

Demo.

【讨论】:

【解决方案2】:

用途:

printf("\%02hhx", pt->GUID[i]);

因为printf()variadic function,所以它的参数是promoted to inthh 修饰符告诉printf() 对应值的类型是unsigned char 而不是int

【讨论】:

    【解决方案3】:

    改为转换为 unsigned char,以避免前导 1 位被解释为负值。

    【讨论】:

      【解决方案4】:

      我注意到当数字大于 99x 时,你得到了 F。

      我写这个是为了测试它并在http://www.cplusplus.com/reference/cstdio/printf/发现了hh前缀

      #include "stdio.h"
      
      char GUID[16];
      
      int main() {
      int i;
      for(i=0;i<16;i++) {
          GUID[i]=i*i;
      }
      for(i=0;i<16;i++) {
          printf("\\%02.2hhx\n", GUID[i]);
      }
      return 0;
      }
      

      【讨论】:

        【解决方案5】:

        在所有平台上使用一个小的自己的实现来解决这个问题:

        char hex[] = "0123456789abcdef";
        
        void printHex(unsigned char byte) {
            printf("%c%c", hex[byte>>4], hex[byte&0xf]);
        }
        

        【讨论】:

          猜你喜欢
          • 2015-12-09
          • 2017-01-09
          • 2022-12-20
          • 1970-01-01
          • 2013-05-07
          • 1970-01-01
          • 2018-11-07
          • 2011-05-25
          相关资源
          最近更新 更多