【问题标题】:Convert a long hex string in to int array with sscanf使用 sscanf 将长十六进制字符串转换为 int 数组
【发布时间】:2011-11-19 22:23:46
【问题描述】:

我有一个类似的输入

char *input="00112233FFAA";
uint8_t output[6];

sscanfinput 转换为output 的最简单方法是什么? (最好是没有循环的 1 行)我想到的解决方案不能扩展到 20+ 十六进制字符串。

sscanf(input, "%x%x%x%x%x",output[0], output[1]....output[5]);

【问题讨论】:

  • sscanf(input, "%2x%2x%2x%2x%2x%2x",&output[0], &output[1], ..., &output[5]);
  • 请注意,使用%x 解析到uint8_t 位置可能会导致内存损坏,因为它实际上需要unsigned int
  • 我称之为字节数组或八位字节字符串。

标签: c scanf


【解决方案1】:

为什么scanf可以很容易地手写:

const size_t numdigits = strlen(input) / 2;

uint8_t * const output = malloc(numdigits);

for (size_t i = 0; i != numdigits; ++i)
{
  output[i] = 16 * toInt(input[2*i]) + toInt(intput[2*i+1]);
}

unsigned int toInt(char c)
{
  if (c >= '0' && c <= '9') return      c - '0';
  if (c >= 'A' && c <= 'F') return 10 + c - 'A';
  if (c >= 'a' && c <= 'f') return 10 + c - 'a';
  return -1;
}

【讨论】:

  • 该标准在技术上不保证连续的字母字符,但在 A-F 范围内,您的代码应该在仍在使用它的两台计算机上的 EBCDIC 中工作。
  • @ChrisLutz:确实,关于允许的编码有一些假设。在最坏的情况下,您可以用查找表替换 toInt 正文...
【解决方案2】:

如果您不想使用循环,则需要显式写出所有六个(或二十个)数组位置(尽管 %x 不是正确的转换字符 - 它需要一个指向 unsigned int 的指针作为它的相应的论点)。如果你不想把它们都写出来,那么你需要使用一个循环——不过它可以很简单:

for (i = 0; i < 6; i++)
    sscanf(&input[i * 2], "%2hhx", &output[i]);

【讨论】:

  • hh 对我没用。我不得不解析成unsigned int 的临时数组,然后手动复制到uint8_t 数组。
  • @ChrisWue:您可能没有符合 C99 标准的标准库(例如 Microsoft C 库)。
【解决方案3】:

这是一个替代实现。

#include <stdio.h>
#include <stdint.h>

#define _base(x) ((x >= '0' && x <= '9') ? '0' : \
         (x >= 'a' && x <= 'f') ? 'a' - 10 : \
         (x >= 'A' && x <= 'F') ? 'A' - 10 : \
            '\255')
#define HEXOF(x) (x - _base(x))

int main() {
    char input[] = "00112233FFAA";
    char *p;
    uint8_t *output;

    if (!(sizeof(input) & 1)) { /* even digits + \0 */
        fprintf(stderr,
            "Cannot have odd number of characters in input: %d\n",
            sizeof(input));
        return -1;
    }

    output = malloc(sizeof(input) >> 1);

    for (p = input; p && *p; p+=2 ) {
            output[(p - input) >> 1] =
            ((HEXOF(*p)) << 4) + HEXOF(*(p+1));
    }

    return 0;
}

【讨论】:

    猜你喜欢
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    • 2019-08-04
    • 2012-07-22
    • 2020-07-18
    相关资源
    最近更新 更多