【字符编码】本地编码与GBK、GB2312

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


QString::fromLocal8Bit你说是本地编码转为qstring的utf-16,
这里的本地编码是电脑的一项设置吗,在哪里可以设置查看吗,
以及如果这个设置好之后是不是意味着这个电脑只能输出这个编码的文本,比如记事本中写一些文字存储时就以这种进行编码,以及如果我写一些汉字,然后按照啊ASCII编码,会怎么存储,其他程序读取又会怎么样
你提到GBK和gb2312这两种编码有什么异同,介绍对比下
我再vs中代码编辑时写的字符串比如char*p=“haha123”,这个字符串“haha123”他是什么编码保存是什么决定,是所在的cpp文件编码决定的吗,和你之前提到的本地编码有没有什么关系

你提的这几个问题都直击编码的核心痛点(环境依赖、编码规则、工程实践),我会逐个拆解,用通俗的语言+实操步骤讲清楚,帮你彻底理清这些关联。

一、关于 QString::fromLocal8Bit 与“本地编码”的核心问题

1. 本地编码是电脑的设置吗?在哪里查看/设置?

结论:是!本地编码(也叫“系统区域设置/ANSI编码”)是操作系统的核心字符编码配置,不同系统的查看/设置方式不同:

✅ Windows 系统(重点,因为Windows是本地编码差异最大的系统)
  • 查看方式
    1. 控制面板 → 时钟和区域 → 区域 → 管理 → “非Unicode程序的语言”(核心!这就是本地编码的关键配置);
    2. 命令行执行 chcp 命令(显示当前控制台编码,与本地编码强相关):
      • 中文系统默认 chcp 936 → 对应 GBK 编码;
      • 英文系统默认 chcp 1252 → 对应 Latin1(CP1252);
      • 日文系统 chcp 932 → 对应 Shift_JIS。
  • 设置方式
    控制面板 → 区域 → 管理 → “更改系统区域设置” → 选择对应语言(需重启生效)。
✅ Linux/macOS 系统
  • 现代 Linux/macOS 已默认将本地编码设为 UTF-8,几乎无需手动设置;
  • 查看方式:终端执行 locale 命令,重点看 LC_CTYPE(字符编码),正常输出是 zh_CN.UTF-8/en_US.UTF-8
  • 若需修改:编辑 /etc/locale.conf(Linux)或 ~/.bash_profile(macOS),设置 LC_ALL=zh_CN.UTF-8,重启终端生效。
2. 本地编码设置后,是不是电脑只能输出该编码的文本?

结论:不是“只能”,而是“默认”——系统会优先用本地编码处理非Unicode程序/老旧接口,但现代程序(如新版记事本、VS)支持多编码。
以 Windows 记事本为例:

  • 保存文本时,默认编码是「ANSI」(即本地编码,中文系统=GBK);
  • 但你可以手动选择“UTF-8”“UTF-8 with BOM”“Unicode(UTF-16)”,并非只能用本地编码;
  • 只有老旧程序(如Win95时代的软件) 会强制依赖本地编码,现代软件都支持UTF-8/UTF-16。
3. 汉字按 ASCII 编码存储会怎样?其他程序读取会怎样?

核心前提:ASCII 编码仅覆盖 0~127 的字符(数字、字母、基础符号),根本不支持汉字

  • 存储时:
    若强行将汉字按 ASCII 编码处理(比如用 char[] = "汉字" 直接赋值),系统会:
    1. 先将汉字按本地编码(如GBK)转为字节流(“汉”→GBK字节 0xBA 0xBA,“字”→0xD7 0xD6);
    2. 这些字节的数值(如0xBA=186)超过了ASCII的127,因此无法用ASCII表示,会被当作“扩展ASCII”(非标准)存储;
  • 读取时:
    其他程序读取这些字节时,若按 ASCII 解析 → 会把 0xBA/0xD7 等字节解析为乱码(比如显示 □、? 或西欧特殊字符);
    若按正确的本地编码(如GBK) 解析 → 能正常显示汉字;
    若按 UTF-8 解析 → 因 GBK 字节不符合 UTF-8 编码规则,显示 �(替换字符)或乱码。

二、GBK 与 GB2312 的异同对比

GB2312 和 GBK 都是中文 Windows 系统的核心本地编码,属于“国标汉字编码”,核心关系是「GBK 兼容并扩展了 GB2312」:

维度GB2312 (1980年)GBK (1995年)
核心定位基础中文编码,仅覆盖常用汉字扩展中文编码,兼容GB2312
字符范围1. 6763个常用简体汉字;
2. 682个符号(数字、字母、标点);
3. 不支持繁体、生僻字、日韩汉字
1. 完全兼容GB2312(GB2312的字符编码不变);
2. 新增20000+个字符:繁体汉字、生僻字、日韩汉字、少数民族字符;
3. 总覆盖字符超21000个
编码规则双字节编码:
- 高字节:0xA1~0xF7;
- 低字节:0xA1~0xFE
双字节编码(兼容GB2312规则):
- 高字节:0x81~0xFE;
- 低字节:0x40~0xFE(排除0x7F);
(扩展了高字节范围,支持更多字符)
字节长度所有汉字/符号均为双字节兼容GB2312,汉字/扩展字符均为双字节
使用场景老旧系统/程序(如DOS、早期软件)Windows 95+ 中文系统默认ANSI编码(chcp 936),是目前最常用的中文本地编码
兼容性仅能解析GB2312字符,无法解析GBK新增字符可解析所有GB2312字符,也能解析自身新增字符

总结:GBK 是 GB2312 的“超集”——你可以把 GB2312 理解为“基础汉字库”,GBK 是“基础+扩展汉字库”,现代 Windows 中文系统的本地编码默认是 GBK(而非 GB2312),只是习惯上仍统称“ANSI/GBK”。

三、VS中 char* p = "haha123" 的编码问题

1. 字符串 "haha123" 的编码由什么决定?

核心结论:由CPP文件的编码 + VS的“字符集编译选项” 共同决定,和系统“本地编码”有间接关联,但非直接决定

拆解关键细节:

(1)第一步:CPP文件中字符串的存储编码

你在VS编辑器里写的 "haha123"(或含汉字的 "哈哈123"),首先会以CPP文件的编码保存到磁盘:

  • VS默认的CPP文件编码:
    • 新建文件:UTF-8 with BOM(VS2019+);
    • 旧文件:可能是 GBK(本地编码)或 UTF-8;
  • 查看/修改CPP文件编码:VS → 文件 → 高级保存选项 → 可选择“编码”(如UTF-8、简体中文(GB2312)、Unicode(UTF-16))。
(2)第二步:编译时的编码转换(关键!)

VS编译时,会把CPP文件中的字符串常量("haha123")转换为程序运行时的字节编码,转换规则由项目的“字符集”选项决定:

  • 项目属性 → 配置属性 → 常规 → 字符集:
    使用多字节字符集(MBCS)
    • VS会将CPP文件中的字符串,从「文件编码」转换为系统本地编码(如中文Windows=GBK);
    • 例:CPP文件是UTF-8编码的 "哈哈123",编译后 char* p 指向的字节流是 GBK 编码(0xB9 0xFE 0xB9 0xFE 0x31 0x32 0x33);
      使用Unicode字符集(默认推荐)
    • VS会将字符串视为宽字符(wchar_t*),默认按 UTF-16 编码存储;
    • 若写 char* p = "haha123",VS会隐式将 UTF-16 转换为本地编码(MBCS),等价于 MultiByteToWideChar 系统调用;
    • 推荐写法:wchar_t* p = L"haha123"(直接UTF-16,无转换)。
2. 与“本地编码”的关系?
  • 间接关联:VS编译时的“多字节字符集”选项,本质是将字符串转换为系统本地编码;
  • 无直接关联:若CPP文件编码是UTF-8,且你显式用 u8"haha123"(C++11+ UTF-8 字面量),则 char* p 指向的是 UTF-8 字节流,与本地编码无关;
  • 例:
    • 中文Windows(本地编码GBK),CPP文件编码UTF-8,字符集选“多字节”:char* p = "哈哈" → 编译后是 GBK 字节;
    • 同样环境,写 char* p = u8"哈哈" → 编译后是 UTF-8 字节(0xE5 0x93 0x88 0xE5 0x93 0x88),和本地编码无关。

总结

1. 本地编码核心
  • 是系统配置(Windows“非Unicode程序的语言”、Linux/macOS locale),Windows中文默认GBK,Linux/macOS默认UTF-8;
  • 现代程序可绕过本地编码(如记事本选UTF-8保存),仅老旧程序强制依赖;
  • 汉字无法用ASCII存储,强行存储会变成乱码字节,需按对应编码(GBK/UTF-8)解析才正常。
2. GBK vs GB2312
  • GBK是GB2312的超集,兼容所有GB2312字符,新增繁体/生僻字;
  • Windows中文系统的本地编码是GBK(chcp 936),而非GB2312。
3. VS中字符串编码
  • 由「CPP文件编码」+「VS字符集编译选项」决定;
  • “多字节字符集”会转换为本地编码,“Unicode字符集”默认UTF-16;
  • 显式用 u8"" 可强制UTF-8,脱离本地编码依赖(推荐跨平台开发用)。
4. 实操建议
  • 跨平台项目:CPP文件编码设为UTF-8(无BOM),用 u8"" 定义UTF-8字符串,Qt中用 QString::fromUtf8() 转换,彻底避开本地编码;
  • Windows仅本地程序:可临时用 fromLocal8Bit(),但优先逐步迁移到UTF-8;
  • VS开发:字符集选“Unicode”,用 wchar_t/L""u8"",减少编码转换坑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值