转自:https://blog.csdn.net/liangbch/article/details/79608635

关于字符编码
1. 西方文字的编码。

1.1 ASCII 码,ASCII是通用的英文字符的编码,对于英文字符,他采用7位2进制数来表示一个英文字符,我们知道1个byte包含8个bit,对于ASCII码来说,最高bit为0.

1.2 ISO 8859,西方广泛使用的编码标准。用于西方文字,有256个码位,前128个与ASCII标准兼容,后128个用于表示欧洲文字中的其他字母。

1.3 当然含有其他各种各样的编码,这里略去不谈。

2. 中文和东方文字的编码

2.1. GB 2312-1980。
这个标准由中国国家标准总局1980年发布的。 共收入汉字6763个和非汉字图形字符682个.每个汉字由2个字节表示,第一个字节的范围是0xa1-0xfe,第二个字节的范围也是0xa1-0xfe,其编码空间为94*94=8836。但实际上,并非编码空间的每个字符都有定义。6763+682=7445<8836

2.2.GBK
GBK亦采用双字节表示,是对GB2312的扩充。第1个字节的范围是0x81-0xfe,第2个字节的范围也是0x40-0xfe,剔除 xx7F一条线,即第2个字节不能是0x7f。总计23940 个码位,共收入汉字21003个、符号883个,并提供1894个造字码位,简、繁体字融于一库。中文Windows3.2和苹果OS以GB2312为基本汉字编码.

2.3. GB18030 
GB18030 有两个标准,GB18030-2000 和GB18030-2005,可看做GBK的扩展。标准采用单字节、双字节和四字节三种方式对字符编码。编码空间更大,当然也更复杂。

2.4.GB13000
GB13000有2个版本,为1993版和2010版. GB13000.1-1993 是1993年发布的,国际正式的叫法是ISO/IEC 10646。包含20902个汉字。这里解释下汉字字符集。GB2312规定的6763个常用汉字可称为汉字基本集。后期陆续增加了6个辅助集。这7个汉字集包含了所有的汉字,包括简体汉字,繁体汉字,中日韩统一(CJK)汉字,总共包含了大约4万9千个汉字,其中20902个汉字被GB13000.1-1993版定义。GB13000标准是一个宏大的标准,按其定义,总编码位置高达2,147,483,648个。

2.5.UNICODE。UNICODE是由一个多语言软件制造商组成的统一码联盟制定的标准,和ISO这个组织不同,这个标准试图将不同的国家的语言统一到一个标准中。UNICODE有多种不同的编码方式,包括UTF-8,UTF-16,UTF-32等。其中UTF-8,UTF-16最为常用。在Visual studio 中,如果宏UNICODE被定义,则字符串用UTF-16表示。对于UTF16编码,所有的英文字符和汉字都用2个字节来表示。对于英文字符,高8位为0. 对于UTF-8编码来说,英文字符仍用8比特表示,兼容ASCII,汉字则采用3字节来表示。

关于文本文件的格式

在中文Windows,你如果用记事本创建一个文件,点击“另存为”菜单,你会发现,有一个编码选项,可选择编码类型。见下图

编码类型的默认值是ANSI,其他的选项为 unicode, unicode big endian和utf-8. 其中ANSI意味着英文字符用ASCII的格式存储,中文字符的编码格式是GB2312。 中文windows默认的代码页是936.在命令行窗口输入命令"MODE CON CP"可显示你的windows的代码页设置。因为GB2312的代码页是936,所以ANSI格式的编码即GB2312编码。unicode意味着所有字符均使用2字节的形式来存储,utf-8意味着,英文字符采用1字节来存储,汉字采用3字节老存储。对于ANSI编码格式,文件内容不包括格式标识。对于其他编码格式,文件头部有2到3个字节的标记。具体为:

utf8:      头部标识为 0xef, 0xbb, 0xbf。
unicode : 头部标识为 0xff, 0xfe.  对于英文字符,第1字节为其ASCII码。第2字节为0.
unicode big endiam :  头部标识为0xfe, 0xff. 对于英文字符,第1字节为0,第2字节为其ASCII码。

Visual studio 源程序的编码类型
Visual Stuio 2013 支持的编码类型多达100多种。如果你点击"文件"->"高级保存选项",你可以选择各种各样的编码格式,见下图。其中"UTF-8 带签名"指文件头部有格式标识,"无签名"指文件头部没有格式标识。

Visual C++ 与unicode
Visual C++ 工程文件有一个很重要的属性,字符集,可设为"使用UNICODE字符集" 或"使用多字节字符集", 当设置为前者,工程文件中增加宏定义“_UNICODE”和"UNICODE". 当设置为使用多字节字符集,工程文件中增加宏定义“_MBCS", 是否有UNICODE这个宏对Windows API 函数的调用有很大的影响。事实上,Win32 API实际上有两个版本。一个版本接受MBCS字符串,另一个接受Unicode字符串。例如:其实根本没有SetWindowText()这个API函数,相反,真实的函数是SetWindowTextA()和SetWindowTextW()。后缀A表明这是MBCS函数,后缀W表示这是Unicode版本的函数。当UNICODE被定义,所有的函数并被替换成W结尾的函数,否则,函数被替换成A结尾的函数。下面例子来自winuser.h中的SetWindowText()函数的声明部分:

#ifdef UNICODE
#define SetWindowText SetWindowTextW
#else
#define SetWindowText SetWindowTextA
#endif // !UNICODE  
可见,API函数根据定义UNICODE与否决定指向Unicode版本还是MBCS版本。

“UNICODE" 不但影响Windows API 函数的调用,也影响的C++/C运行时刻库中部分函数的调用。实际上,关于字符串的C/C++函数也有2套版本,接收ANSI字符串格式的版本,和接收UNICODE字符串格式的版本。如printf 可接受ANSI字符串,而wprintf则接受UNICODE字符串的版本。他们的参数类型也相同,前者的字符串地址的类型是"char *",后者字符串地址的类型是"wchar_t *". 为了简化编程,即使用同样的源代码,编译为使用UNICODE字符集的版本和使用使用多字节字符集的版本。VC 中定义也一个tchar.h的头文件。当"_UNICODE"未被定义(或_MBCS被定义)时,    宏"_TCHAR" 被定义为 "char",  宏"_T"被定义为空,在编译时被预处理移除。当"_UNICODE"被定义时,"_TCHAR" 被定为为"wchar_t", 而"_T" 则被替换为"L", "L"的作用是将后面的字符或字符串转换成相应的Unicode 形式。

下面的代码显示了,当UNICODE被定义和没有定义时。程序的行为。

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <tchar.h>
#include <locale.h>
 
void dump_buff(_TCHAR  *buff, int len)
{
    printf("buff[]=\n{");
    for (int i = 0; i < len; i++)
    {
#ifdef _UNICODE
        printf("0x%04X,", (_TUCHAR)buff[i]);
#else
        printf("0x%02X,", (_TUCHAR)buff[i]);
#endif
    }
    printf("}\n");
}
 
 
int main(int argc, char* argv[])
{
    _TCHAR  buff[20];
    memset(buff, 0, sizeof(buff));
    dump_buff(buff, sizeof(buff) / sizeof(_TCHAR));
 
#ifdef _UNICODE
    setlocale(LC_CTYPE, "");    //去掉这句,wprintf 不显示任何输出
    wcscpy(buff, _T("你好,世界\n"));
    wprintf(buff);
#else
    strcpy(buff, _T("你好,世界\n"));
    printf(buff);
#endif
 
 
    dump_buff(buff, sizeof(buff) / sizeof(_TCHAR));
    return 0;
}
当工程的属性设为“使用UNICODE字符集”,程序输出如下

buff[]=
{0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000
0,0x0000,}
你好,世界
buff[]=
{0x4F60,0x597D,0x002C,0x4E16,0x754C,0x000A,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000
0,0x0000,}
当工程的属性设为”使用多字节字符集”时,程序输出如下
buff[]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}
你好,世界
buff[]=
{0xC4,0xE3,0xBA,0xC3,0x2C,0xCA,0xC0,0xBD,0xE7,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}
值得注意的是,当使用wprintf是,必须调用"setlocale(LC_CTYPE,"");" 否则这个函数不工作,更多的详情,请参阅https://www.cnblogs.com/findumars/p/6147442.html

编译器对字符串的解释
不管你的VC++源程序文件是以ANSI格式保存的,还是以UTF-8格式保存的,VC++编译器总是把一个字符串解释为ANSI格式的字符串。这看起来没有问题。但是如果你想让你的程序跨平台,这就有问题了。Qt 可编写跨平台的代码,即源代码不需修改或者只做很小的调整,就可以编译成运行在windows,linux或者Andriod平台上的目标程序。如果程序需要显示或者输出英文以外的文字,最方便的编码就是utf-8.  如果你的Qt 使用MinGW编译,且将Qt工程中的源代码文件的编码设为UTF-8. 那么,输出没有问题,也不会遭遇到乱码问题。但是,如果你的Qt使用Visual studio 作为编译器.  将默认编码设为"UTF-8",并将"UTF-8 BOM"设为"如果编码是UTF-8则添加"。见下图。

用Qt编写的文件可用Visual Studio正确打开,但是在运行时则会显示乱码。这是因为VC的编译器总是将字符串解释为ANSI格式的字符串,即使源文件的编码是UTF-8也不例外。但是Qt的程序需要将字符串解释为UTF-8编码的字符串。为此,需要在源文件开头添加如下编译指示。加上这句话。Qt的程序就能正确工作了

#pragma execution_character_set("utf-8")
————————————————

Visual studio 与字符编码浅析相关推荐

  1. Visual Studio——理解多字节编码与Unicode码

    多字节字符与宽字节字符 char与wchar_t 我们知道C++基本数据类型中表示字符的有两种:char.wchar_t.  char叫多字节字符,一个char占一个字节,之所以叫多字节字符是因为它表 ...

  2. visual studio asmx 调试_通过Windows Visual Studio远程调试WSL2中的.NET Core Linux应用程序...

    最近两天在Linux中调试.NET Core应用程序,同时我发现在Linux中调试.NET Core应用程序并不容易.一直习惯在Visual Studio中进行编码和调试.现在我想的是可以简单快速的测 ...

  3. 通过Windows Visual Studio远程调试WSL2中的.NET Core Linux应用程序

    最近两天在Linux中调试.NET Core应用程序,同时我发现在Linux中调试.NET Core应用程序并不容易.一直习惯在Visual Studio中进行编码和调试.现在我想的是可以简单快速的测 ...

  4. Visual Studio代码:高级用户指南

    In this guide, you'll learn how to take advantage of Visual Studio Code to supercharge your developm ...

  5. Visual Studio——多字节编码与Unicode码

    多字节字符与宽字节字符 1) char与wchar_t 我们知道C++基本数据类型中表示字符的有两种:char.wchar_t.  char叫多字节字符,一个char占一个字节,之所以叫多字节字符是因 ...

  6. Visual Studio 2010/2013 UTF8编码调试时显示中文

    VisualStudio 2010 SP1环境 1.设置string默认编码为utf8,只需要在文件头部加入以下代码 1 #pragma execution_character_set("u ...

  7. python 字符编码处理_浅析Python 字符编码与文件处理

    Python字符编码 目前计算机内存的字符编码都是Unicode,目前国内的windows操作系统采用的是gbk. python2默认的字符编码方式是ASCII python3默认的字符编码方式是Un ...

  8. Visual Studio开发工具分配字符数组的问题

    当我们在使用c语言创建字符串时一般是这样的: char* str = (char*)malloc(20); memset(str,0,20); 申请完内存需要使用memset来初始化字符串! 而使用V ...

  9. Visual Studio 增加每行最多字符数限制参考线

    文章目录 1 下载插件Editor Guidelines 2 Visual Studio 中设置 3 命令设置 1 下载插件Editor Guidelines Editor Guidelines:ht ...

最新文章

  1. softmax layer 简单理解以及实际例子【有白话讲解】
  2. 程序员修炼之道:从小工到专家阅读笔记01
  3. springboot中aop的应用场景_自然语言处理工具包 HanLP在 Spring Boot中的应用
  4. Python语言学习:利用sorted对字典按照value进行递减排序,输出列表,并给定排名索引,组成新字典输出
  5. Educational Codeforces Round 32
  6. mysql数据库面试总结
  7. JQuery源码笔记jQuery.access研究学习(13)
  8. 【flink】95-260-045-源码-检查点-CheckPoint
  9. deepin安装tomcat
  10. Android代码如何监控apk安装 卸载 替换
  11. 记第十七次CCF CSP认证
  12. 破解Visio时office失效,激活失败
  13. 汽车故障诊断技术【4】
  14. PostgreSQL 数据库导入导出
  15. 淘宝数据魔方技术架构
  16. pandas中每个元素减去所在行的平均值
  17. php栏目一二级排序,灵动标签完美实现当前栏目高亮-支持二级栏目及内容页及栏目排序...
  18. lae界面开发工具入门之介绍十--如何打包资源文件?
  19. java工程师项目经验_最新JAVA工程师个人简历中的项目经验范文.doc
  20. 手机版的python怎么用,手机上如何使用python

热门文章

  1. Maya:绑定—机械臂动画
  2. NVIDIA GPU虚拟化七版迭代,如今再秀一波!
  3. 一名优秀的clickbaitor必备的技能XD
  4. NETALLY LRAT-2000/LRAT-1000/LRAT-2000-KIT有线链路通测试仪2020重磅登场
  5. 【操作系统】——PV操作
  6. 光学效应类有哪些最新发表的毕业论文呢?
  7. Android 上实现非root的 Traceroute -- 非Root权限下移植可执行二进制文件 脚本文件
  8. 购物搜索引擎/比较购物网站
  9. Android Monkey测试入门:安装sdk、studio、模拟器,并分析monkey日志
  10. 语音交互设计的一点认知