如何转换十六进制字符串以插入C中的二进制文件

How to convert string of hex to insert into binary file in C

我需要接收一些字符串输入,并将其转换为相等的十六进制数,然后将其放入二进制文件中。

        char *fpath = argv[3];
        FILE *f = fopen(fpath, "wb+");
        char buf[1000];
        char *input = "46AB";

        unsigned int value = strtol(input , NULL, 16);
        sprintf(buf, "\x%x", value);
        fseek(f, 2, SEEK_SET);
        fputs(buf, f);

在它生成的文件中

5C 78 34 36 61

虽然我需要它看起来像

46 AB

有没有一种优雅的方式来做到这一点?

您的 sprintf 调用创建了字符串

\x46ab

你在没有进一步解释的情况下将这六个字符写入文件,所以这就是你在文件中看到的内容(十六进制字节 5c 78 34 36 61 62)。

要获得所需的十六进制到二进制的转换,同时避免字节顺序问题并预期任意长度 input 字符串的可能性,您可以一次一个字节地执行此操作,代码如下这个:

char *p;
for(p = input; *p != '[=11=]'; p += 2) {
    unsigned int x;
    if(sscanf(p, "%2x", &x) != 1) break;
    putc(x, f);
}

这使用sscanfinput字符串转换为十六进制,一次两个字符(两个十六进制数字,或一个输出字节)。

我还用更长的输入字符串对其进行了测试:

input = "0102034a4b4c";

这是快速但不完美的代码。如果 input 包含奇数个字符,它将出现异常,并且它也不会特别优雅地处理非十六进制字符。

一项改进是对 scanf 使用稍微晦涩的 %n 格式说明符来准确发现它每次消耗了多少字符:

for(p = input; *p != '[=13=]'; ) {
    unsigned int x;
    int n;
    if(sscanf(p, "%2x%n", &x, &n) != 1) break;
    putc(x, f);
    p += n;
}

虽然我没有对它进行详尽的测试,但它应该对格式错误的 input 字符串更有效。 (我几乎从不使用 scanf 系列中的函数,更不用说像 %n 这样更晦涩的格式说明符了,但这是我所知道的少数几个有吸引力的问题之一,替代方案要麻烦得多。)

P.S。我摆脱了你的 fseek 电话,因为我不确定它在那里做什么,它混淆了我的测试。需要的话可以放回去。