【问题标题】:Char to Hex not showing string's ASCII value字符到十六进制不显示字符串的 ASCII 值
【发布时间】:2012-04-09 10:05:08
【问题描述】:

玩弄 C 或 C99,我试图了解转换、位移和十六进制值的工作原理。

我有以下问题

char c[4];
c[0] = 0x41;
c[1] = 0x42;
c[2] = 0x43;
c[3] = 0x00;
printf("%s", c); //prints ABC
printf("%X", c); //prints 99B11760

99B11760 从何而来?

同样...

int main() {
    char a = 'a'; //ascii value is 0x41 (Mistake I made, 'a' is 0x61, 'A' is 0x41) 
    printf("%X\n",a); //outputs "61"? (THIS IS CORRECT OUTPUT, 'a' != 0x41)
}

我一直在寻找解决方案来解决将 Hex 值存储到 char 中的类似问题,但我无法理解的是某些存储值与 ASCII 值不对应的原因或位置。由于它既不是 ASCII 十六进制值、十进制值或八进制值,所以使用 printf("%X\n", c); 时打印的是什么值;

【问题讨论】:

  • 这段代码有问题。你在对编译器撒谎,告诉它你在传递一件事,而实际上你传递了其他东西。停止做无意义的事情,谜团就会消失。
  • 不能同意更多@DavidSchwartz,但我发布这个问题的原因是为了帮助我了解像这样的错误代码在哪里出现错误。我确实尽量不发布愚蠢的问题,大多数时候我很幸运能找到答案,但这确实让我追了好一阵子。

标签: c hex printf


【解决方案1】:

允许 C 中的数组变量自动转换为地址值(也称为指针值)。您看到的输出与数组的内容完全无关。

也许你打算这样做?

char c[4];
c[0] = 0x41;
c[1] = 0x42;
c[2] = 0x43;
c[3] = 0x00;
printf("%X", *(unsigned int*)c );

【讨论】:

  • 我希望不会,因为那仍然是未定义的行为。
  • 这确实更有意义,我没有注意到 printf 语句需要取消引用才能使用正确的类型。 'printf("%d c[0] int 值\n", *c); //打印 65' 'printf("%X c[0] 十六进制值\n", *c); //打印 0x45' 'printf("%s c[0] str value\n", c); //打印“ABC”'再次感谢您。
【解决方案2】:

99B11760 从何而来?

这是c在你强制它衰减为指针后碰巧有的值。

我一直在寻找解决这个问题的方法

什么问题?有没有你想做却不知道怎么做的事情? “我做了一些没有意义的事情并得到了一个无意义的答案”不是问题。只是不要那样做。

.. 但我遇到的问题是理解为什么或在哪里打印 61 而不是 ASCII 十六进制值 0x41。不是十进制值,也不是八进制值。

如您所见,它应该没有特定的价值。但它必须是一些东西。如果你把骰子扔到空中,结果是 2,你想知道为什么它是 2 吗?当然不是。只有当它应该是一回事但是另一回事时,你才会遇到问题。在这种情况下,应该没有什么。

【讨论】:

    【解决方案3】:
     printf("%X", c); //prints 99B11760
    

    这会调用未定义的行为。 x 转换说明符需要 unsigned int,但您传递的是 char *

    在问题的第二部分中,您应该将 a 转换为 unsigned int

    printf("%X\n", (unsigned int) a);
    

    A ascii 值为0x41,但a ascii 值为0x61

    【讨论】:

      【解决方案4】:

      对于第一个问题,当您使用%X 格式打印c 时,它正在打印数组的地址(第一个字符的地址)。对于第二个问题,这是因为a 的 ASCII 值是 97(十进制),转换为十六进制是 61。如果使用 A 字符,那么它将打印 41,因为大写 A 的 ASCII 值是 65。

      【讨论】:

        【解决方案5】:

        c 是一个指针,因此当您使用除%s 之外的任何内容打印它时,您将得到打印的指针地址。

        【讨论】:

          【解决方案6】:
          int main() {
          char a = 'a'; //ascii value is 0x41
          printf("%X\n",a); //outputs "61"?
          }
          

          在这种情况下,首先将 'a'(ascii value = 97) 存储到字符 a 中,因此字符 a 包含 97,然后将 97 以十六进制形式打印为“0x61”

          char c[4];
          c[0] = 0x41;
          c[1] = 0x42;
          c[2] = 0x43;
          c[3] = 0x00;
          printf("%s", c); //prints ABC
          printf("%X", c); //prints 99B11760
          

          在这种情况下

                   '0x41' in decimal value is 65 is 'A' in ASCII
                   '0x42' in decimal value is 66 is 'B' in ASCII
                   '0x43' in decimal value is 67 is 'C' in ASCII   
                   '0x00' in decimal value is 00 is null in ASCII   
          

          如果格式说明符是字符/字符串类型,它将输出'ABC'

          【讨论】:

          • printf("%X", c); //prints 99B11760,对于这一行,当我在 cygwin 上编译和执行时,我得到了 22CCEC,但当我在在线编译器“codepad”上编译和执行时,同样如此我正在获得 BF859328 值,请查看此 @codepad.org/8B2Fg9y5
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-14
          • 2017-03-11
          • 2014-01-02
          • 2010-10-04
          • 2017-12-02
          • 2015-05-22
          相关资源
          最近更新 更多