如何将十六进制字符串转换为C中的二进制文件

Posted

技术标签:

【中文标题】如何将十六进制字符串转换为C中的二进制文件【英文标题】:How to convert string of hex to insert into binary file in C 【发布时间】:2021-11-20 03:13:44 【问题描述】:

我需要接受一些字符串形式的输入,并将其转换为相同的十六进制数,并将其放入二进制文件中。

        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

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

【问题讨论】:

您需要使用fwritevalue 中的数据直接写入文件。 snprintffputs 是字符串/文本运算符。您不能使用它来生成二进制数据。您只需要fwrite(&value, sizeof(value), 1, f) 我相信这两个 cmets 对于常见的 little-endian 机器都是错误的。 如果您想以十六进制值查看数据,您可以查看hex edit 【参考方案1】:

您的sprintf 调用创建了字符串

\x46ab

并且您将这六个字符写入文件而无需进一步解释,这就是您在文件中看到的内容(十六进制字节 5c 78 34 36 61 62)。

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

char *p;
for(p = input; *p != '\0'; 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 != '\0'; ) 
    unsigned int x;
    int n;
    if(sscanf(p, "%2x%n", &x, &n) != 1) break;
    putc(x, f);
    p += n;

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

附:我摆脱了你的fseek 电话,因为我不确定它的用途,它混淆了我的测试。如果需要,您可以将其放回原处。

【讨论】:

以上是关于如何将十六进制字符串转换为C中的二进制文件的主要内容,如果未能解决你的问题,请参考以下文章

如何将一串二进制数转换为 C 中的字符(每个字符都必须有一个半字节)?

将“ff0000”之类的字符串转换为目标c中的十六进制数

求c语言将十进制数转换为16进制的函数

如何在C中将十六进制字符串转换为二进制字符串?

将文件中的字符串转换为十六进制(Ruby)第二部分

c++中如何将十进制数字换为ASLL码中的字母