1. char16_t 与 char32_t
在 C++98 中,为了支持 Unicode 字符,使用 wchar_t 类型来表示“宽字符”,但并没有严格规定位宽,而是让 wchar_t 的宽度由编译器实现,因此不同的编译器有着不同的实现方式,GNU C++ 规定 wchar_t 为 32 位,Visual C++ 规定为 16 位。由于 wchar_t 宽度没有一个统规定,导致使用 wchar_t 的代码在不同平台间移植时,可能出现问题。这一状况在 C++11 中得到了一定的改善,从此 Unicode 字符的存储有了统一类型:
char16_t 用于存储 UTF-16 编码的 Unicode 字符
char32_t 用于存储 UTF-32 编码的 Unicode 字符
char16_t 和 char32_t 的宽度由其名称可以看出 char16_t 为 16bits,char32_t 为 32bits。至于使用 UTF-8 编码的 Unicode 字符,C++11 还是使用了 8bits 宽度的 char 类型数组来表示 。
除了使用新类型 char16_t 与 char32_t 来表示 Unicode 字符,此外,C++11 还新增了三种前缀来定义不同编码的字符或字符串,新增前缀如下:
u8 表示 UTF-8 编码
u 表示 UTF-16 编码
U 表示 UTF-32 编码
C++98 中有两种定义字符或字符串的方式,一是直接使用单引号或双引号定义多字节字符或字符串,二是通过前缀 L 表示 wchar_t 类型的宽字符或字符串。至此,C++ 中共有 5 种定义字符或字符串的方式。
在书写 Unicode 字符时,C++11 规定可以使用 \u 加上 4 个十六进制数或者使用 \U 加上 8 个十六进制数的 Unicode 码值来表示一个 Unicode 字符,比如汉字’你’可以表示如下:
char16_t c = u'\u4f60';
char32_t C = U'\U00004f60';
前缀 u 表示使用 UTF-16 编码存储 Unicode 字符,U 使用 UTF-32 编码存储 Unicode 字符。
2.影响字符串正确处理的因素
在使用不同方式定义不同编码的字符串时,我们需要注意影响字符串处理和显示的几个因素有编辑器、编译器和输出环境。
代码编辑器采用何种编码方式决定了字符串最初的编码,比如编辑器如果采用GBK,那么代码文件中的所有字符都是以GBK编码存储。当编译器处理字符串时,可以通过前缀来判断字符串的编码类型,如果目标编码与原编码不同,则编译器会进行转换,比如C++11中的前缀u8表示目标编码为UTF-8的字符,如果代码文件采用的是GBK,编译器按照UTF-8去解析字符串常量,则可能会出现错误。
//代码文件为GBK编码
#include
#include
using namespace std;
int main()
{
const char* sTest = u8"你好";
for(int i=0;sTest[i]!=0;++i)
{
cout<
}
return 0;
}
//编译选项:g++ -std=c+