在看Qt相关的文档时,不断看到Qt对于i18n和Unicode的支持如何,一直没有个直观和底层的认识,最近写了些简单的例子,感觉结合实例能更好理解Qt内部对于字符串存储的转换机制。
下面的例子都以"中文"这个简单的字符串作为示例。
编译和调试工具:GCC &GDB
本地locale:zh_CN.UTF-8
字符 '中',Unicode码值U+4E2D, 对应的UTF-8编码形式为 E4 B8 AD (大端)
字符 “文”, Unicode码值U+6587, 对应的UTF-8编码形式为 E6 A6 87 (大端)
例子1 .不使用Qt,直接用char数组存储字符串
输出结果:
使用gdb查看buffer中存储的值
可以很清楚的观察到此时buffer中存储的就是“中文”对应的UTF-8编码,由于此时输出的字符串和locale采用的是相同的编码格式,因此不会出现乱码形式。
示例2 使用QString存储字符串,并利用QChar看清楚“中文”这个字符串在QString中究竟是如何存储的。
上面的QString::data()的作用是返回一个指向所存储数据的QChar *指针,正如Qt的文档中所描述的一样,QString可以看作是QVector<QChar>
下面使用gdb查看pch所指向的区域存储的内容
仔细观察,请注意QChar中存放的是16 bit 的Unicode的值;答案很明显,pch指向的区域存放的值依次是 U+00e4,U+00b8,U+00ad,U+00e6,U+0096,U+0087,U+0000这七个Unicode码值。
是不是觉得这个序列看着有些眼熟?对了,这和第一个例子中gdb中查看到的值很相像,确切的说是值相同,不同的是示例1中的每个字节在在示例2中都用2字节来表示——这就是Qt所谓的QString的内部存储使用Unicode的底层含义!
这里,把上面的脉络稍微梳理一下:
首先,我们从示例1中已经知道,源代码中的“中文"在我的实验环境下(locale为zh_CN.UTF-8)被编码为8 bit 的 Ascii 字符串“ 0xe4 0xb8 0xad 0xe6 0x96 0x87 0x00”;
其次,在示例2中定义QString 类型的变量chinese时用"中文"为其初始化,因为QString内部存储采用Unicode,所以每个字符用16 bit来表示,因此0xe4 扩展为 0x00e4, 0xb8扩展为0x00b8,依次类推。
因此,“中文”在QString内部的存储形式就是
0xe4 0x00 0xb8 0x00 0xad 0x00 0xe6 0x00
0x96 0x00 0x87 0x00 0x00 0x00
如何,看了这个简单的例子,是否对Qt的Unicode支持还感觉很模糊呢?
下面的例子都以"中文"这个简单的字符串作为示例。
编译和调试工具:GCC &GDB
本地locale:zh_CN.UTF-8
字符 '中',Unicode码值U+4E2D, 对应的UTF-8编码形式为 E4 B8 AD (大端)
字符 “文”, Unicode码值U+6587, 对应的UTF-8编码形式为 E6 A6 87 (大端)
例子1 .不使用Qt,直接用char数组存储字符串
char
buffer[]
=
"
中文
"
;
cout << buffer << endl;
cout << buffer << endl;
输出结果:
使用gdb查看buffer中存储的值
(gdb) x
/
8xb
&
buffer
0xbfa20879 : 0xe4 0xb8 0xad 0xe6 0x96 0x87 0x00 0x20
0xbfa20879 : 0xe4 0xb8 0xad 0xe6 0x96 0x87 0x00 0x20
可以很清楚的观察到此时buffer中存储的就是“中文”对应的UTF-8编码,由于此时输出的字符串和locale采用的是相同的编码格式,因此不会出现乱码形式。
示例2 使用QString存储字符串,并利用QChar看清楚“中文”这个字符串在QString中究竟是如何存储的。
QString chinese="中文";
QChar * pch=chinese.data();
QChar * pch=chinese.data();
上面的QString::data()的作用是返回一个指向所存储数据的QChar *指针,正如Qt的文档中所描述的一样,QString可以看作是QVector<QChar>
下面使用gdb查看pch所指向的区域存储的内容
(gdb) x
/
16xb pch
0x804b192 : 0xe4 0x00 0xb8 0x00 0xad 0x00 0xe6 0x00
0x804b19a : 0x96 0x00 0x87 0x00 0x00 0x00 0x00 0x00
0x804b192 : 0xe4 0x00 0xb8 0x00 0xad 0x00 0xe6 0x00
0x804b19a : 0x96 0x00 0x87 0x00 0x00 0x00 0x00 0x00
仔细观察,请注意QChar中存放的是16 bit 的Unicode的值;答案很明显,pch指向的区域存放的值依次是 U+00e4,U+00b8,U+00ad,U+00e6,U+0096,U+0087,U+0000这七个Unicode码值。
是不是觉得这个序列看着有些眼熟?对了,这和第一个例子中gdb中查看到的值很相像,确切的说是值相同,不同的是示例1中的每个字节在在示例2中都用2字节来表示——这就是Qt所谓的QString的内部存储使用Unicode的底层含义!
这里,把上面的脉络稍微梳理一下:
首先,我们从示例1中已经知道,源代码中的“中文"在我的实验环境下(locale为zh_CN.UTF-8)被编码为8 bit 的 Ascii 字符串“ 0xe4 0xb8 0xad 0xe6 0x96 0x87 0x00”;
其次,在示例2中定义QString 类型的变量chinese时用"中文"为其初始化,因为QString内部存储采用Unicode,所以每个字符用16 bit来表示,因此0xe4 扩展为 0x00e4, 0xb8扩展为0x00b8,依次类推。
因此,“中文”在QString内部的存储形式就是
0xe4 0x00 0xb8 0x00 0xad 0x00 0xe6 0x00
0x96 0x00 0x87 0x00 0x00 0x00
如何,看了这个简单的例子,是否对Qt的Unicode支持还感觉很模糊呢?