C++开发时字符编码的选择
最近看了很多有关字符编码的讨论帖子, 自己也做了很多尝试, 针对linux和windows上字符编码的选择做了个简单整理, 在此做个记录
首先是基础编码知识, 下面我列出的4个编码方式或字符集是我们应该了解的
1. ANSI
2. UNICODE
3. UTF8
4. GB2312
这里因为个人专业水平有限, 为了避免错误的解释, 不对这些概念做详细解释, 而是贴出一些我查找到的有用的资料
Unicode 和 UTF-8 有什么区别 ---- https://www.zhihu.com/question/23374078
简体汉字编码方案(GB2312、GBK等)以及全角、半角、CJK ---- https://zhuanlan.zhihu.com/p/27099035
ANSI编码与代码页 ---- https://zhuanlan.zhihu.com/p/27136737
接下来是我自己的验证和尝试的过程以及自己的知识总结
先贴出来我在windows和linux环境下的测试代码, 编译器我分别用linux GCC, MSVC v100 和 MSVC v141做了测试
#ifdef _WIN32
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif
#endif #include <stdio.h>
#include <string> int main()
{
std::string testANSI = "中国";
std::wstring testUNICODE = L"中国"; printf("sizeof wchar_t : %lu \n", sizeof(wchar_t));
printf("length of std::string : %lu \n", testANSI.length());
printf("length of std::wstring : %lu \n", testUNICODE.length()); printf("ANSI :");
for (size_t idx = ; idx < testANSI.length(); ++idx)
{
printf(" %hhx", testANSI[idx]);
}
printf("\n"); printf("UNICODE :");
for (size_t idx = ; idx < testUNICODE.length(); ++idx)
{
printf(" %hx", testUNICODE[idx]);
}
printf("\n"); return ;
}
下面贴出不同平台不同编码方式下程序的输出结果
1.windows环境下, 源代码编码为ANSI(本地gb2312)
2.windows环境下, 源代码编码为UTF8, 不使用execution_character_set宏
3.windows环境下, 源代码编码为带BOM的UTF8, 不使用execution_character_set宏
4.windows环境下, 源代码编码为UTF8, 使用execution_character_set宏
5.windows环境下, 源代码编码为带BOM的UTF8, 使用execution_character_set宏
6. Ubuntu linux环境下, 源代码编码为带BOM的UTF8, 使用默认编码方式编译(这里我指定的编码方式即默认编码)
7. Ubuntu linux环境下, 源代码编码在UTF8和GBK之间变换, 指定不同编码输出
MSVC v100和MSVC v141(对应vs2010和vs2017)的结果相同, 上方windows平台运行截图均为vs2017编译运行结果
对上述结果进行总结
windows环境下, 源文件编码为不带BOM的UTF8时, 由于编译器没能正常识别文件编码, string的内容被保存为文件的原本内容(utf8), wstring保存的结果均是宽字符字符串, 而非UNICODE字符集
windows环境下, 源文件编码为带BOM的UTF8或ANSI时, 编译器能够正常识别文件编码(或者直接用本地编码解析), string内容被保存为gb2312字符串, wstring内容均为UNICODE字符集
上面两种情况, 仅当源文件编码为带BOM的UTF8且程序使用execution_character_set宏指明UTF8时, string内容才会被存为UTF8格式, UNICODE不受影响内容正常
linux环境下在文件输入编码格式正确的情况下, 不管怎么搞内容都一致, 且GCC编译器可以兼容带BOM的UTF8源文件
综上, 总结我个人的看法建议 :
纯Windows平台开发, 源代码使用ANSI, 字符类型选择wchar_t, 杜绝char和string, 并且避免使用POSIX, 使用MSVC编译器一定要在visual studio中选择使用UNICODE字符集(影响_UNICODE和UNICODE两个宏声明, 使用多字节则会声明宏_MBCS)
跨平台, 类Unix占大头则源代码使用UTF8, Windows占大头则源代码使用UTF8 with BOM并且选择不受影响的编译器, 字符类型选择char, 在调用API和IO时根据需要进行转换
重要的一点, 尽可能避免在源代码中使用ASCII码以外的任何字符(学好english是关键呐)
最后是我查阅和借鉴的资料,帖子,博文:
截止到 2017 年,C++ 对于 Unicode 支持情况如何 ---- https://www.zhihu.com/question/55601459
目前(2020 年)开发WINDOWS程序,用UNICODE还是多字节更实际 ---- https://www.zhihu.com/question/364285465
[C/C++] 各种C/C++编译器对UTF-8源码文件的兼容性测试(VC、GCC、BCB)---- https://www.cnblogs.com/zyl910/archive/2012/07/26/cfile_utf8.html
以上, 如有错误疏漏, 请务必指出, 任何问题欢迎讨论, 转载请注明, 感谢
C++开发时字符编码的选择的更多相关文章
- python全栈开发-Day7 字符编码总结
python全栈开发-Day7 字符编码总结 一.字符编码总结 1.什么是字符编码 人类的字符--------->翻译--------->数字 翻译的过程遵循的标准即字符编码(就是一个字符 ...
- python全栈开发-Day6 字符编码
python全栈开发-Day6 字符编码 一 .了解字符编码的知识储备 一 .计算机基础知识 二 .文本编辑器存取文件的原理(nodepad++,pycharm,word) #1.打开编辑器就打开了启 ...
- Java 运行时字符编码与解码
以下仅为个人学习的记录,如有疏漏不妥之处,还请不吝赐教. Java在运行时字符char采用UTF-16进行编码. public class RuntimeEncoding { public stati ...
- 本地文件读取(csv,txt)时字符编码问题解决
今天进行csv文件读取时,老是入库为空,因为其中有中文字符,我要通过中文字符映射成相应的编号(上升:1011,下降:1012),于是怎么也取不到编号.刚开始以为程序映射出了问题,最后日志打出来后,发现 ...
- python全栈开发_day7_字符编码,以及文件的基本读取
一:字符编码 1)什么是字符编码 将人能识别的字符等高级标识符与计算机所能识别的二进制01进行转化,这之间的交流需要一个媒介,进行两种标识符之间的转化. 字节的存储方式为八个二进制位 2)乱码 存放数 ...
- PHP字符编码问题-总结
今天在网上看到一个人的对于php开发中字符编码的总结,感觉不错,摘录如下: 一,php编码转换 1.通过iconv()函数实现编码转换 语法:iconv(s ...
- C++运行字符编码于MSVC和GCC之间的区别
详细请参考这篇博文 http://blog.csdn.net/dbzhang800/article/details/7540905 运行字符编码就是指,当你源代码写下const char* p = & ...
- php接口开发时,数据解析失败问题,字符转义,编码问题
php接口开发时,数据解析失败问题,字符转义,编码问题 情景: A平台--->向接口请求数据---->接口向B平台请求数据---->B平台返回数据给接口---->接口返回数据给 ...
- Java应用开发中的字符集与字符编码
事出有因 在向HttpURLConnection的输出流写入内容时,因没有设置charset,导致接收方对数据的验签不一致. URL url = new URL(requestUrl); //打开连接 ...
随机推荐
- 常用CSS颜色表
1.16进制的CSS颜色代码 > http://www.jsjtt.com/webkaifa/HTML/65.html
- CSS3多栏布局
CSS3多栏布局 分栏数: column-count:auto|num: auto为默认值,表示元素只有一列.num取值为大于0的整数 每栏宽度: column-width:auto|<leng ...
- iframe和DataForm
一.iframe使用 iframe在一个页面中,相当于整个window窗口的子窗口,可通过页面的元素结构查看. <div> <p>学习iframe</p> < ...
- Mysql 的数据导入导出
一. mysqldump工具基本用法,不适用于大数据备份 1. 备份所有数据库: mysqldump -u root -p --all-databases > all_database_sq ...
- Web压测工具之Webbench和http_load
Webbench简介 是知名的网站压力测试工具,能测试处在相同硬件上,不同服务的性能以及不同硬件上同一个服务的运行状况. webbench的标准测试可以向我们展示服务器的两项内容:每秒钟相应请求数和每 ...
- PHP round() 函数
实例 对浮点数进行四舍五入:高佣联盟 www.cgewang.com <?php echo(round(0.60) . "<br>"); echo(round(0 ...
- PHP constant() 函数
实例 返回一个常量的值: <?php//define a constantdefine("GREETING","Hello you! How are you tod ...
- day1. python注释及变量
一.注释 1.单行注释 # # python 2.x print "你好" # python 3.x print("你好") 2.多行注释 ''' ''' 或 ...
- CF习题集一
CF习题集一 一.CF915E Physical Education Lessons 题目描述 \(Alex\)高中毕业了,他现在是大学新生.虽然他学习编程,但他还是要上体育课,这对他来说完全是一个意 ...
- 串行&并行&并发,同步&异步
1. 串行&并行&并发 1.1 串行 这个非常好理解,字面意思,像串成一个串一样,顺序执行 上一个没执行完的话,后面的就必须无条件等待 一般情况就是一个线程里:任务一个接一个执行,类似 ...