【问题标题】:Conversion of unsigned int to hex string without use of sprintf不使用 sprintf 将 unsigned int 转换为十六进制字符串
【发布时间】:2021-01-26 08:55:49
【问题描述】:

我正在尝试实现以下内容(没有 sprintf 或格式化):

    void integer_to_string(unsigned int a, char *string)
{
    char arr[16] = "0123456789abcdef";
    char *p = (char *)&a;
    unsigned int i;

    for (i = 0; i < 4; i++) {
        unsigned char lo = p[i] & 0xf; 
        unsigned char hi = p[i] >> 4;

        string[i*2] = arr[hi];
        string[i*2+1] = arr[lo];
    }
    string[2*i] = '\0';
}

该程序正在从整数 a 转换并将 a 转换为十六进制并将其余部分保存为字符串。因此,它应该将 10 之类的 int 返回到“0000000a”,而是给我一个“0a000000”的值。我究竟做错了什么?如何将 0a 移动到末尾而不是开头。

【问题讨论】:

  • 看起来您的系统对整数使用 little-endian 字节顺序。您需要以相反的顺序遍历该值的字节,或者从右侧开始在字符串中写入字节。选一个。对于不依赖于了解系统字节序的解决方案,您可以改为使用位移位和掩码来实现相同的目的。
  • char *p = (char *)&amp;a; 这是不可移植的,因为 p 指向的 int 字节取决于平台 endianess。看来您的平台是小端的,所以p 从最低字节地址开始。最好在整个 int 上使用 shift 和 mask 操作。
  • 还有一个问题:在进行位旋转时总是使用无符号类型。该标准没有指定char 是有符号还是无符号。如果它是有符号的(x86!),那么p[i] &gt;&gt; 4 可以是算术符号扩展移位,你会得到一些不太正确的东西。如果您正在使用 x86,请尝试将 255 转换为十六进制

标签: c string integer hex unsigned


【解决方案1】:

通过char *p = (char *)&amp;a; 访问正确的有效字节取决于字节序,在 OP 的情况下,顺序错误。


通过使用数学而不是强制转换来获得正确的顺序并避免字节顺序问题:

for (i = 0; i < 8; i++) {
    unsigned char ch = (a >> ((32-4) - i*4)) & 0xF; 
    string[i] = arr[ch];
}
string[i] = '\0';

存在简化。

【讨论】:

  • 或者更好的是,使用 CHAR_BIT + sizeof
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-12
  • 2019-08-04
  • 2020-07-18
  • 1970-01-01
相关资源
最近更新 更多