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); //打开连接 ...
随机推荐
- 小特跨境电商ERP桌面版 1.不止包括进销存 还能算毛利
经过近几年跨境电商ERP的开发,加上对跨境电商行业的业务积累,开发出一套适合中小跨境电商公司使用的ERP软件.欢迎选购.支持目前流行的各大电商平台,如速卖通.敦煌网.亚马逊.Shopee.Wish等. ...
- DJANGO-天天生鲜项目从0到1-009-购物车-Ajax实现添加至购物车功能
本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...
- DJANGO-天天生鲜项目从0到1-002-用户模块-注册
本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...
- Linux中profile和bashrc的区别
profile主要设置系统环境参数(可类比为Windows的系统环境变量),如$PATH /etc/profile ~/.bash_profile bashrc主要用来设置bash命令,如命令别名,a ...
- Java8线程池ThreadPoolExecutor底层原理及其源码解析
小侃一下 日常开发中, 或许不会直接new线程或线程池, 但这些线程相关的基础或思想是非常重要的, 参考林迪效应; 就算没有直接用到, 可能间接也用到了类似的思想或原理, 例如tomcat, jett ...
- Letex中表格问题
最近在学习使用Letex,在学习过程中碰到很多小问题,故记之. 以下是一个参数表的实例(绘成三线表的形式). \begin{table}[hp] %%参数: h:放在此处 t:放在顶端 b:放在底端 ...
- luogu P4516 [JSOI2018]潜入行动
LINK:潜入行动 初看题感觉很不可做 但是树形dp的状态过于明显. 容易设\(f_{x,j,l,r}\)表示x为根子树内放了j个设备且子树内都被覆盖l表示x是否被覆盖r表示x是否放设备的方案数. 初 ...
- 星屑幻想 optimal mark
LINK :SP839 星屑幻想 取自 OJ 的名称 小事情...题目大意还是要说的这道题比较有意思,想了一段时间. 给你一张图 这张图给答案带来的贡献是每条边上两个点值得异或 一些点的值已经被确定 ...
- 教你不编程快速解析 JSON 数据
JSON 是一种轻量级的,不受语言约束的数据存储格式,大部分编程语言都可以解析它,并且对编程人员也十分友好.我们在进行通讯/数据交互时,非常经常用到 JSON 格式. 但是,我们在进行数据存储的时候, ...
- Netty(一):server启动流程解析
netty作为一个被广泛应用的通信框架,有必要我们多了解一点. 实际上netty的几个重要的技术亮点: 1. reactor的线程模型; 2. 安全有效的nio非阻塞io模型应用; 3. pipeli ...