最近看了很多有关字符编码的讨论帖子, 自己也做了很多尝试, 针对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++开发时字符编码的选择的更多相关文章

  1. python全栈开发-Day7 字符编码总结

    python全栈开发-Day7 字符编码总结 一.字符编码总结 1.什么是字符编码 人类的字符--------->翻译--------->数字 翻译的过程遵循的标准即字符编码(就是一个字符 ...

  2. python全栈开发-Day6 字符编码

    python全栈开发-Day6 字符编码 一 .了解字符编码的知识储备 一 .计算机基础知识 二 .文本编辑器存取文件的原理(nodepad++,pycharm,word) #1.打开编辑器就打开了启 ...

  3. Java 运行时字符编码与解码

    以下仅为个人学习的记录,如有疏漏不妥之处,还请不吝赐教. Java在运行时字符char采用UTF-16进行编码. public class RuntimeEncoding { public stati ...

  4. 本地文件读取(csv,txt)时字符编码问题解决

    今天进行csv文件读取时,老是入库为空,因为其中有中文字符,我要通过中文字符映射成相应的编号(上升:1011,下降:1012),于是怎么也取不到编号.刚开始以为程序映射出了问题,最后日志打出来后,发现 ...

  5. python全栈开发_day7_字符编码,以及文件的基本读取

    一:字符编码 1)什么是字符编码 将人能识别的字符等高级标识符与计算机所能识别的二进制01进行转化,这之间的交流需要一个媒介,进行两种标识符之间的转化. 字节的存储方式为八个二进制位 2)乱码 存放数 ...

  6. PHP字符编码问题-总结

    今天在网上看到一个人的对于php开发中字符编码的总结,感觉不错,摘录如下: 一,php编码转换        1.通过iconv()函数实现编码转换                语法:iconv(s ...

  7. C++运行字符编码于MSVC和GCC之间的区别

    详细请参考这篇博文 http://blog.csdn.net/dbzhang800/article/details/7540905 运行字符编码就是指,当你源代码写下const char* p = & ...

  8. php接口开发时,数据解析失败问题,字符转义,编码问题

    php接口开发时,数据解析失败问题,字符转义,编码问题 情景: A平台--->向接口请求数据---->接口向B平台请求数据---->B平台返回数据给接口---->接口返回数据给 ...

  9. Java应用开发中的字符集与字符编码

    事出有因 在向HttpURLConnection的输出流写入内容时,因没有设置charset,导致接收方对数据的验签不一致. URL url = new URL(requestUrl); //打开连接 ...

随机推荐

  1. webview访问URL

    //    // Do any additional setup after loading the view. //    //创建WKWebView //    WKWebView *web = ...

  2. css中使用浮动的情况和清除浮动的方法

    1.使用浮动时出现的情况: (1)使块元素在一行显示 (2)使内嵌元素支持宽高 (3)不设置宽高的时候宽度由内容撑开 (4)换行不被解析(故使用行内元素的时候清除间隙的方法可以使用浮动) (5)元素添 ...

  3. 2020 年百度之星&#183;程序设计大赛 - 初赛三

    2020 年百度之星·程序设计大赛 - 初赛三解题思路及代码(Discount.Game.Permutation) 1.Discount Problem Description学皇来到了一个餐馆吃饭. ...

  4. Python os.dup() 方法

    概述 os.dup() 方法用于复制文件描述符 fd.高佣联盟 www.cgewang.com 语法 dup()方法语法格式如下: os.dup(fd); 参数 fd -- 文件描述符 返回值 返回复 ...

  5. PHP xml_set_unparsed_entity_decl_handler() 函数

    定义和用法 xml_set_unparsed_entity_decl_handler() 函数规定当解析器在 XML 文档中找到无法解析的实体时被调用的函数. 如果成功,该函数则返回 TRUE.如果失 ...

  6. PHP xml_error_string() 函数

    定义和用法 xml_error_string() 函数获取 XML 解析器的错误描述.高佣联盟 www.cgewang.com 如果成功,该函数则返回错误描述.如果失败,则返回 FALSE. 语法 x ...

  7. @property@classmethod@staticmethod

    一.静态属性@property将方法标记成数据属性:可以访问实例和类的属性 @classmethod标记成类的方法,不需要实例化,可以类直接调用的方法.可以访问类的属性方法,不能访问实例的 class ...

  8. 【Python 实例】面向对象 | 请输入一周中某天的名称的第一个字母来判断以下是星期几,如果第一个字母一样则继续判断第二个字母

    [Python 实例]面向对象 | 请输入一周中某天的名称的第一个字母来判断以下是星期几,如果第一个字母一样则继续判断第二个字母 题目: 解答: 运行结果: 题目: 请输入一周中某天的名称的第一个字母 ...

  9. 嵌入式Linux串口编程简介

    文章目录 简介 用到的API函数 代码 简介 嵌入式Linux下串口编程与Linux系统下的编程没有什么区别,系统API都是一样的.嵌入式设备中串口编程是很常用的,比如会对接一些传感器模块,这些模块大 ...

  10. JS 前端框架笔记

    Swiper轮播图插件使用     官网:https://www.swiper.com.cn/     先引用插件的css.js文件     然后找到需要使用的轮播图文件中去把HTML css和JS代 ...