如何将十六进制字符串转换为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
有没有一种优雅的方式来做到这一点?
【问题讨论】:
您需要使用fwrite
将value
中的数据直接写入文件。
snprintf
和 fputs
是字符串/文本运算符。您不能使用它来生成二进制数据。您只需要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);
这使用sscanf
将input
字符串一次转换为十六进制,两个字符(两个十六进制数字,或一个输出字节)。
我还用更长的输入字符串对其进行了测试:
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中的二进制文件的主要内容,如果未能解决你的问题,请参考以下文章