C语言实现十六进制与二进制的相互转换
本文详解如何利用C语言的位运算和文件流操作,将存储为人类可读十六进制(如"ab cd")的文本数据转换为紧凑的二进制格式,反之亦然。核心在于理解每两个十六进制字符对应一个字节(8位)的二进制值。
基本原理
十六进制数(Hexadecimal)使用0-9和a-f表示数值。因为单个十六进制位(Nibble)最大值为15(即f),仅需4个比特位即可表示。而标准字符类型 char 占用1个字节(8位),因此正好可以容纳两个十六进制位。
- 压缩效果:例如文本中的 "ab" 占用2个字节,转换为二进制后存入
char d仅占1个字节,空间利用率提高一倍。 - 注意事项:转换后的前32个值对应ASCII控制字符,不可见但数据完整保留。
十六进制文本转二进制
该过程的核心逻辑是循环读取两个合法的十六进制字符,将它们合并为一个字节写入目标文件。
第1步:初始化文件指针与缓冲区
打开源文本文件只读,创建输出二进制文件只写。需确保路径正确。
第2步:读取并过滤非法字符
在循环中逐个读取字符。由于十六进制文本通常包含空格或换行符作为分隔,遇到 ' ' 或 '\n' 时不应计入计数,需通过索引回退或 continue 跳过。
第3步:字符转数值与位运算合并
对读取到的有效字符进行转换:
- 若为数字 '0'-'9',减去 ASCII '0' 得到数值。
- 若为字母 'a'-'f',减去 ASCII 'a' 并加 10 得到数值。
利用位运算将两次读取的数值合并至 d:
d <<= 4:将已累积的高位向左移动4位,腾出低位空间。d |= c:将当前读取的低4位数值或运算到d的低位。
第4步:写入结果
当成功凑齐两个十六进制位后,将合并后的字节 d 写入输出文件。
以下是完整的 C 语言源码示例:
#include <stdio.h>
int main() {
FILE *in = fopen("./data.txt", "r"); // 源:十六进制文本
FILE *out = fopen("./data.bin", "wb"); // 目标:二进制文件
if (!in || !out) return -1;
while (1) {
char c;
unsigned char d = 0;
// 内层循环尝试读取两个有效的十六进制字符
for (int i = 0; i < 2; ++i) {
// 读取1个字节
if (fread(&c, 1, 1, in) != 1) {
goto end_process; // 文件结束
}
// 跳过空格和换行
if (c == ' ' || c == '\n') {
i--;
continue;
}
// 字符转十进制数值 (0-15)
if (c >= '0' && c <= '9') {
c -= '0';
} else if (c >= 'a' && c <= 'f') {
c -= ('a' - 10);
} else if (c >= 'A' && c <= 'F') {
c -= ('A' - 10);
} else {
printf("Invalid hex char: %c\n", c);
continue; // 忽略无效字符
}
// 位操作合并
d <<= 4;
d |= c;
}
fwrite(&d, 1, 1, out);
}
end_process:
fclose(in);
fclose(out);
return 0;
}
验证转换结果是否准确,可在 Linux 环境下使用命令 hexdump -C data.bin 查看二进制文件的十六进制视图,应与原始文本内容一致。

二进制转十六进制文本
这是上述过程的逆操作:读取二进制文件中的一个字节,提取其高4位和低4位,分别转换为对应的十六进制字符,并格式化输出(如添加空格)。为了保持阅读习惯,代码实现了每4个字节插入一个换行的逻辑。
#include <stdio.h>
int main() {
FILE *in = fopen("./data.bin", "rb"); // 源:二进制文件
FILE *out = fopen("./data_hex.txt", "w"); // 目标:十六进制文本
if (!in || !out) return -1;
int count = 0; // 用于计算每行打印几个字节
char space = ' ';
char enter = '\n';
unsigned char byte_val;
char hex_chars[2];
while (fread(&byte_val, 1, 1, in) == 1) {
// 高4位取出并转字符
hex_chars[0] = (byte_val >> 4) & 0xf;
// 低4位取出并转字符
hex_chars[1] = byte_val & 0xf;
// 辅助函数逻辑:数值转 Hex Char
auto to_hex_char = [](unsigned char val) -> char {
if (val < 10) return val + '0';
return val - 10 + 'a';
};
hex_chars[0] = to_hex_char(hex_chars[0]);
hex_chars[1] = to_hex_char(hex_chars[1]);
fwrite(hex_chars, 1, 2, out); // 写入两个十六进制字符
fwrite(&space, 1, 1, out); // 写入空格分隔
count++;
if (count % 4 == 0) {
fwrite(&enter, 1, 1, out); // 每4组(8个字符)换行
}
}
fclose(in);
fclose(out);
return 0;
}
注意:在实际工程应用中,建议引入标准的 strtoul 或库函数处理更复杂的边界情况,但对于底层算法学习而言,手动模拟位运算有助于深入理解计算机内存表示。
总结
C语言在处理数据编码转换时,通过对位的精细操控(左移、与运算),可以实现高效的文本与二进制数据间的互转。掌握这一技巧对于开发自定义协议、数据压缩工具或底层驱动具有重要意义。
以上就是C语言实现十六进制与二进制的相互转换的详细内容,更多关于C语言进制转换的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









