16进制编码,分别解析为gb2312和utf8两种编码
#include stdio.h #include stdlib.h #include string.h #include iconv.h #include errno.h // 辅助函数将16进制字符串转换为字节数组 // 例如E4BDA0 - {0xE4, 0xBD, 0xA0} int hex_to_bytes(const char *hex, unsigned char *bytes) { size_t len strlen(hex); if (len % 2 ! 0) return -1; // 长度必须为偶数 for (size_t i 0; i len; i 2) { sscanf(hex i, %2hhx, bytes[i / 2]); } return len / 2; } // 函数 1: 解析 UTF-8 16进制字符串 // 因为 Linux 终端本身是 UTF-8所以直接转换并打印即可 void parse_as_utf8(const char *hex_str) { int len strlen(hex_str) / 2; unsigned char *bytes (unsigned char *)malloc(len 1); int byte_len hex_to_bytes(hex_str, bytes); if (byte_len 0) { bytes[byte_len] \0; // 添加字符串结束符 printf(UTF-8 解析结果: %s\n, (char *)bytes); } else { printf(UTF-8 解析失败: 无效的16进制输入\n); } free(bytes); } // 函数 2: 解析 GB2312 16进制字符串 // 需要通过 iconv 将 GB2312 转换为 UTF-8 才能在终端显示 void parse_as_gb2312(const char *hex_str) { int in_len strlen(hex_str) / 2; unsigned char *in_bytes (unsigned char *)malloc(in_len); if (hex_to_bytes(hex_str, in_bytes) 0) { printf(GB2312 解析失败: 无效的16进制输入\n); free(in_bytes); return; } // 准备 iconv 转换 // 使用 GB18030 替代 GB2312 兼容性更好涵盖了GBK和所有汉字 iconv_t cd iconv_open(UTF-8, GB18030); if (cd (iconv_t)-1) { perror(iconv_open 失败); free(in_bytes); return; } size_t in_left in_len; size_t out_left in_len * 3 1; // UTF-8 最长占3-4字节分配充足空间 char *out_buf (char *)malloc(out_left); char *out_ptr out_buf; char *in_ptr (char *)in_bytes; memset(out_buf, 0, out_left); // 执行转换 if (iconv(cd, in_ptr, in_left, out_ptr, out_left) (size_t)-1) { printf(GB2312 解析失败: 转换过程中出错\n); } else { printf(GB2312 解析结果: %s\n, out_buf); } iconv_close(cd); free(in_bytes); free(out_buf); } int main() { // 测试数组 const char *hex_array[] { E4BDA0E5A5BD, // 你好 的 UTF-8 编码 B0A1C4DE, // 啊呢 的 GB2312/GBK 编码 NULL }; for (int i 0; hex_array[i] ! NULL; i) { printf(原始16进制: %s\n, hex_array[i]); // 分别调用两个解析函数 parse_as_utf8(hex_array[i]); parse_as_gb2312(hex_array[i]); printf(--------------------------\n); } return 0; }