美食网站开发步骤,grace8WordPress主题,什么优化,深圳网站开发外包正确使用 Unicode 和 MBCS 字符集
在 Windows 下做开发#xff0c;初学者经常面临字符集选择的问题。本文详细解释 MBCS 字符集和 Unicode 字符集的正确使用方法#xff0c;以及为什么写程序要用 Unicode 字符集。同时对 UTF-8 做了简单介绍。
在程序中正确使用字符集
以 …正确使用 Unicode 和 MBCS 字符集
在 Windows 下做开发初学者经常面临字符集选择的问题。本文详细解释 MBCS 字符集和 Unicode 字符集的正确使用方法以及为什么写程序要用 Unicode 字符集。同时对 UTF-8 做了简单介绍。
在程序中正确使用字符集
以 VC 为例微软在 VC6.0 的时候创建项目的默认字符集是 MBCS。从 VC2002就是 VC7.0开始默认字符集就变为了 Unicode直到今天。
为了减少字符编码造成的种种问题请务必确保整个项目使用相同的字符集编码。比如如果设置项目字符集为 Unicode那么整个项目都要用 Unicode 方式处理字符串。具体方法
1. 设置项目字符集
有两种方法设置项目字符集。
方法一在项目属性中设置
以 VC2010 Express 为例在 Solution Explorer 右击项目 - Properties打开的属性窗口中左侧选择 Configuration Properties / General 分类右边将 Character Set 设置为 Use Unicode Character Set 即表示将项目设置为 Unicode 字符集设置为 Use Multi-Byte Character Set 即表示将项目设置为 MBCS 字符集。
方法二在代码中设置
在代码的最顶部增加以下代码表示程序使用 Unicode 字符集
#define UNICODE
#define _UNICODE在代码的最顶部增加以下代码表示程序使用 MBCS 字符集
#undef UNICODE
#undef _UNICODE备注_UNICODE 用于 C 运行库UNICODE 用于 WINAPI。
2. 写程序时使用对应的字符集
对于 MBCS 字符集char 定义字符串字符和字符串常量直接使用例如“Hello” 表示 MBCS 字符串字符串函数可以使用 strlen、strcpy、strcmp 等。STL 可以使用 string。
对于 Unicode 字符集wchar_t 定义字符串字符和字符串常量加 L 前缀例如Lhello 表示 Unicode 字符串字符串函数可以使用 wcslen、wcscpy、wcscmp 等。STL 可以使用 wstring。
如果需要同时适用 Unicode 和 MBCS 两种字符集编码TCHAR 定义字符串字符和字符串常量加 _T()例如_T(hello) 表示 Unicode/MBCS 自适应字符串字符串函数可以使用 _tcslen、_tcscpy、_tcscmp 等。
具体每个字符串函数在不同字符集编码下的函数名请参考微软的帮助文档。
通过示例展现 Unicode 比 MBCS 的优势
实验环境 Windows 7 VC2010 Express EasyX_20220116。在 Win10 下可以得到同样的结果因为代码中涉及到英文中文韩文字符需要将 .cpp 文件以 UTF-8 编码保存。方法File - Save xxx.cpp As…在文件另存为对话框里“保存”按钮右边有一个向下的箭头点击后选择“Save with Encoding…”同意覆盖原文件然后 Encoding 选择 Unicode (UTF-8 with signature) - Codepage 65001Line endings 不用调整确定保存即可。
两个示例程序的具体设置与代码
第一个示例程序
项目名称 TestUnicode 项目类型Win32 Console Application 项目字符集Unicode
#include graphics.h
#include conio.hint main()
{wchar_t s[] L厉害了我的国;initgraph(640, 480);settextstyle(24, 0, L微软雅黑);outtextxy(10, 30, s);_getch();closegraph();return 0;
}第二个示例程序
项目名称 TestMbcs 项目类型Win32 Console Application 项目字符集MBCS
#include graphics.h
#include conio.hint main()
{char s[] 厉害了我的国;initgraph(640, 480);settextstyle(24, 0, 微软雅黑);outtextxy(10, 30, s);_getch();closegraph();return 0;
}原理解释
ASCII 码规定了每个字符一个字节前 128 个属于常规 ASCII 码后 128 个属于扩展 ASCII 码。常规 ASCII 码里面含有英文大小写字母、阿拉伯数字、常见标点符号等。扩展 ASCII 码里面是一些不常用的字符。
于是在过去想要表示多语言的时候就利用了扩展 ASCII 码不常用的特点将两个连续的扩展 ASCII 码表示成其它语言。
例如中文的 GB2312 编码将汉字分成 94 个区和 94 个位区和位分别使用了扩展 ASCII 码的 161~254 这个范围。“中国”两字的区位码分别是 5448 2590那么可以构造一个这样的程序暂时忽略编译警告
// 设置为 MBCS 字符集
#undef UNICODE
#undef _UNICODE#include graphics.h
#include conio.hint main()
{// “中”的区位码是 54 48“国”的区位码是 25 90char s[] {160 54, 160 48, 160 25, 160 90, 0};initgraph(640, 480);settextstyle(24, 0, 微软雅黑);outtextxy(10, 30, s);_getch();closegraph();return 0;
}执行这个程序可以成功的输出“中国”两个字。
这就是在 MBCS 字符集下中文的表示形式。
其他语言类似比如韩文的 EUC-KR 编码过去叫 KSC5601 编码也用的两个扩展 ASCII 码并且范围也是 0xA1-0xFE。台湾地区的 BIG5 编码也覆盖了这个范围。那么问题来了两个扩展 ASCII 码究竟表示中文、韩文还是繁体中文或者别的语言
这取决于操作系统的系统区域locale设置 当 locale 设置为简体中文那么两个连续的扩展 ASCII 码就会根据 GB2312 编码解析 当 locale 设置为韩文那么两个连续的扩展 ASCII 码就会根据 EUC-KR 编码解析。
由此可知
系统区域设置错误MBCS 字符集的字符串就无法正确显示。MBCS 字符集无法实现多语言混合显示。
当编码与 locale 不匹配的时候就会出现“乱码”。
Unicode 字符集整合了全世界所有语言的文字任何语言的任何一个文字在 Unicode 编码中都有唯一的值对应。因此不再需要设置“系统区域locale”也就不会产生“乱码”了。
就像前面的实验看到的那样采用 Unicode 字符集的程序无论是同时显示多少种语言无论在什么语言的操作系统上执行都可以正常显示。
该文章会更新欢迎大家批评指正。
推荐一个零声学院的C服务器开发课程个人觉得老师讲得不错 分享给大家LinuxNginxZeroMQMySQLRedis fastdfsMongoDBZK流媒体CDNP2PK8SDocker TCP/IP协程DPDK等技术内容 点击立即学习C/C后台高级服务器课程