概述
字符串显示到UI界面上大致有三个阶段:源文件编码格式、编译存储编码格式、执行编码格式
1,源文件编码格式
我们的C/C++源文件一般有GBK、UNICODE(UTF8、UTF16、UTF32)等编码格式,其中UTF8分为带BOM和不带BOM,BOM其实就是标记双字节或者四字节字符是大端还是小端存储,所以其实UTF8是不需要BOM标记的。VC编译器不认不带BOM的UTF8文件,也就是VC编译器会把不带BOM的UTF8源文件当成ANSI编码处理,这种情况下如果你的代码里的字符串有中文字符肯定会乱码,原因是编译器不能正确转换字符串到存储编码格式。
2,编译存储编码格式
即编译器将源文件中的字符串常量(例如字符串 "中国" )编译存储到静态存储区中所用的编码格式 ,说明下 :L"中国",u"中国",U"中国" 等字符串常量显示指定了存储编码格式,编译器会按照你指定的去转码存储到静态存储区。 那么 char str[] = "中国" 这种字符串编译存储编码到底用什么格式呢?分两个阶段,首先在编译后字符串"中国"就存在静态存储区,然后运行时用这个内存初始化字符数组;
(1)VC编译器 在在VC下和本地化locale有关,如果你的系统是简体中文那VC编译时会把字符串转成ANSI编码来存储,当然你可以通过指令更改:
方式一,工程属性 》配置属性 》C/C++ 》命令行 》其他选项,在这里输入/execution-charset:utf-8,那么整个工程中的字符串都将转码成UTF8作为存储编码格式;另外在VS2015中还有指令/source-charset:utf-8指示源文件是utf8格式,指令/utf-8指示源文件编码和编译存储编码都是utf8,对于源文件是无BOM的很有效。
方式二,在源文件里加#pragma execution_character_set("utf-8")指令,这个只对该源文件有效。
(2)g++、Mingw编译器 linux下的编译器大多都是源文件是什么编码那么编译存储就采用什么编码格式,支持编译参数指定格式,-finput-charset指定源文件采用什么格式,-fexec-charset指定编译存储采用的编码格式。
3,执行编码格式
执行编码格式可以通过 setlocale设置,setlocale( LC_ALL, "C" )设置执行编码为ASCII,setlocale( LC_ALL, "chs" );设置简体中文,即运行时exe里的字符串当成ANSI处理,比如说你调用一个带有字符串的系统API(非宽字符版本API),这个API的字符串将被当成ANSI编码;Windows好像是不支持setlocale( LC_ALL, "utf8" )。
所以只有编译器正确识别源文件编码,然后存储编码和执行编码一致才不会乱码;
最后
以上就是无限果汁为你收集整理的C/C++字符乱码研究的全部内容,希望文章能够帮你解决C/C++字符乱码研究所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复