ASCII规定了127个字符编码,而一个字节最多能表示256种。所以可以根据第一位来判断是不是ASCII编码,如果不是说明这是一个多字节编码。
char 与 std::string,英文字符在 UTF-8 中使用一个字节存储,中文字符使用三个字节存储。
C++ 11 开始支持 UTF-8、UTF-16 和 UTF-32 字符串常量的声明,分别使用 u8""、u"" 和 U"" 作为声明的标志。
wchar_t 与 std::wstring解决多字符编码,占两个字节,且需要使用适配的 std::wcout 和 std::wofstream。windows中的编译器一般将wchar_t定为2个字节宽,而linux中的编译器一般定义wchar_t为4字节宽。用常量字符给wchar_t变量赋值时,前面要加L。如: wchar_t wch2 = L’中’;用常量字符串给wchar_t数组赋值时,前面要加L。如: wchar_t wstr2[3] = L”中国”。
编码场景:
乱码的根源:源代码文件(源码字符集)经过编译/链接,生成可执行文件(执行字符集),最后程序运行于实际环境中(运行环境编码)。在这过程中如果有字符集不匹配,最终就无法显示预期的文字信息,甚至产生乱码。
总结起来,要想使程序不会乱码,必须满足:
编译器准确识别了源码字符集,从而得到正确的字符串数据(执行字符集)。
运行环境的编码与执行字符集相同。
一般在程序中为了支持国际化,在程序初始化时,将 locale 设置为系统配置的 Native ANSI 字符集,即执行:setlocale(LC_ALL, “”)。
可以查看文件编码格式:
:file main.cc
main.cc: C++ source text, UTF-8 Unicode text
GCC的源码字符集与执行字符集默认都是UTF-8编码,也就是说默认情况下GCC都是按UTF-8来解析源码,编译后的执行字符集也是UTF-8。当然GCC也提供改变默认情况的编译选项:
-finput-charset=charset 用于指定源码字符集
-fexec-charset=charset 用于指定执行字符集
还有一个参数是:
-fwide-exec-charset=charset
默认情况下,gcc在Windows平台下,宽字符串串常量的每个字符是16位UTF-16类型,在Linux平台下,宽字符串串常量的每个字符是32位UTF-32类型,使用-fwide-exec-charset=charset这个参数,可以改变宽字符串串常量的类型。例如在x86的机器环境,Linux操作系统下,要使例如 L"汉字" 编译后保存为UTF-16的字符串,则可以使用 -fwide-exec-charset=UTF-16LE。
控制台查看编码:
:locale
LANG="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
LC_CTYPE="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_ALL=
https://sf-zhou.github.io/programming/chinese_encoding.html
https://www.iteye.com/blog/jimmee-2165685
https://blog.csdn.net/benkaoya/article/details/59522148