在嵌入式 Linux 开发中,字符编码是引发中文乱码的高频问题。本文梳理常见字符编码格式,并讲解 GCC 编译中如何适配编码,从根源避免乱码。
一、字符编码本质与常见格式
计算机仅能识别二进制数据,字符编码的核心是 “字符 ↔ 二进制数值” 的映射规则,包含两个要素:
- 字符集:定义需表示的字符范围(如中文、英文、符号);
- 编码方式:将字符集中的字符映射为二进制数的具体规则。
乱码的本质:编码(字符转二进制)和解码(二进制转字符)使用了不同的映射规则。
嵌入式开发中最常用的编码格式如下:
表格
| 编码格式 | 字节长度 | 核心特点 | 适用场景 |
|---|---|---|---|
| ASCII | 单字节(0-127) | 仅覆盖英文、数字、基础符号,是所有编码的基础 | 纯英文场景、底层协议交互 |
| GB2312 | 双字节(兼容 ASCII) | 覆盖 6763 个常用中文,无生僻字支持 | 早期中文 Windows、老旧嵌入式设备 |
| GBK | 双字节为主(兼容 GB2312) | 扩展至 2 万 + 中文,包含生僻字、繁体中文 | 早期桌面软件、部分工业嵌入式设备 |
| UTF-8 | 变长字节(1-4 字节,兼容 ASCII) | 支持全球所有语言,无字符覆盖限制 | 现代 Linux 系统、网络传输、嵌入式开发(首选) |
| UTF-16 | 固定 2/4 字节 | 字符定位效率高,存储空间占用大 | Windows 内核、Java 程序、少数嵌入式 GUI 框架 |
二、GCC 编译中的字符编码处理
GCC 默认按 UTF-8 解析源文件,并生成 UTF-8 编码的可执行文件。若源文件编码与默认不符,会直接导致乱码,核心通过两个编译选项适配:
# 1. 指定源文件的编码格式(告诉GCC如何解析源文件)
-finput-charset=编码格式
# 2. 指定可执行文件中字符串的编码格式
-fexec-charset=编码格式
- 支持的编码取值:UTF-8、GBK、GB2312、ASCII 等;
- 默认值:
-finput-charset=UTF-8、-fexec-charset=UTF-8。
典型示例
若源文件是 Windows 下保存的 GBK 编码(比如记事本 / Notepad++ 默认保存),需编译后在 Linux(默认UTF-8 终端)正常显示中文:
gcc -finput-charset=GBK -fexec-charset=UTF-8 -o app app.c