浅析QStringr的Unicode存储特性(二)

在上篇文章中,通过简单的实验弄清楚了QString究竟是如何以Unicode存储字符串的;

接下来考虑另一个问题, 假设"中文"的编码格式不同于locale,例如使用GBK编码,在上文的示例中,还会正常输出“中文"么? 答案是否定的。

考虑一下"中文"GBK编码时的整个转换过程

首先,"中文"对应的GBK编码为“ 0xd6,0xd0,0xce,0xc4,0x00“,由于QString默认情况下认为给定的字符串采用Latin-1编码,所以GBK编码被扩展为对应的16 bit Unicode码值“0x00d6,0x00d0,0x00ce,0x00c4,0x0000";再从QString到std::string的转换中,又由Unicode转换回Latin-1编码"0xd6,0xd0,0xce,0xe4,0x00",实际上又变回了最初的GBK编码,然而locale采用的是UTF-8编码,将GBK编码的字节流输出到编码格式为UTF-8的console,不出现乱码才见鬼呢。

那么,为什么上文中也存在相似的转换,却不会出现乱码呢?因为那里“中文"采用的就是locale编码格式,所以console能正确的识别并显示接受到的字节流。


那么,怎么正确显示GBK编码的"中文"呢?

首先,保证QString中存储的是"中文"对应的Unicode码值“0x4e2d 0x6587",而不是“0x00d6,0x00d0,0x00ce,0x00c4,0x0000",即完成GBK编码到Unicode的翻译。

其次,由于现在QString中的内容是"中文"的Unicode码值,而QString和std::string、const char *、QByteArray之间的转换在默认情况下是采用Latin-1编码,这样就会出现问题——0x4e2和0x6587这样的Unicode码值超出了Latin-1编码的表示范围,转换时会出现信息丢失;解决该问题的方式是显示调用 QString::setCodecForCStrings()来设定QString和const char *之间转换时采用的编码方法。

以下是代码片段
// GBK编码的"中文" 
char  chinese[] = ... {0xd6,0xd0,0xce,0xc4,''} ;

QByteArray gbkbytearray(chinese);
    
QTextCodec 
* gbkcodec  =  QTextCodec::codecForName( " GBK " );
QTextCodec 
* utf8codec  =  QTextCodec::codecForName( " UTF-8 " );

// 设定QString与const char *之间的转换采用UTF-8编码,与locale保持一致
QTextCodec::setCodecForCStrings (utf8codec);
    
// 此时 unicodestr中存放的是“中文"的Unicode码值
QString unicodestr = gbkcodec -> toUnicode(gbkbytearray);

// 同样的,可以借助QChar和GDB来查看QString unicodestr的内部的存储的值
QChar  *  pch = unicodestr.data();
    

// 将QString转换为const char *并输出至console
cout << unicodestr.toStdString().c_str() << endl;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值