彻底搞懂QT中的编码问题

本文深入解析QString乱码根源,探讨其内部Unicode编码机制,提供解决编码转换问题的实用方法,包括QTextCodec的正确使用及常见编码插件的手动加载技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、产生乱码的根源:

  有两种情况:

  1. 字符串存储时的编码和读取时的编码不同 (存是指字符以二进制形式存放在内存中,读是指将二进制数据转成字符串)
  2. 字符不在当前采用的编码表中(比如中文字符在ASCII没有对应)

二、QString采用什么编码

  阅读QT官方文档,上面写的非常清楚:QString将字符存为16位的Unicode码(Unicode只是编码表)当以const char*来构建QString时,QString会调用fromAscii方法来将字符串转换成Unicode码,默认以Latin-1(ISO8859-1)来进行转换,通过QTextCodec::setCodecForCStrings()方法可以设置fromAscii使用的编码。也就是说简单的一个赋值语句:QString = "你好,世界";事实上已经进行了一次编码转换,默认从ISO8859-1转成Unicode码。这也就解释了为什么直接将中文赋值给QString会乱码。

三、如何进行编码转换

  既然QString都是使用Unicode码进行保存,那么我们只要明确两件事就可以应付编码问题:

  1. 字符串存到QString中以什么编码转换到Unicode码
  2. QString中保存的字符串想要以什么编码进行输出(转换后应该以QByteArray返回),即从Unicode码转换成什么编码

  QTextCodec在QT中负责编码的转换,它预定义了多种编码供我们使用,基本的使用方式如下:

QTextCodec* strCode = QTextCodec::codecForCStrings();
QTextCodec* GBK = QTextCodec::codecForName("GBK");
QString str1 = "你好世界";
QString u_str = strCode ->toUnicode(str1);
QString g_str = GBK->fromUnicode(u_str);

  QTextCodec::codecForName("GBK")用来获取一个定义好的编码(查找官方文档),常用的方法有两个:fromUnicode(),从Unicode编码转换到你定义的编码,toUnicode(),从你定义的编码转换到Unicode编码。注意:转换后的结果实际上是QByteArray,QString有一个构造器接受QByteArray,如果将转换结果赋值给QString又要发生一次编码转换(调用fromAscii),所以即使转码完成QString输出还是可能会乱码,这时就要调用QTextCodec::setCodecForCStrings()来将QString使用的默认编码设置成我们想要的编码。但是如果是想输出文本的话,使用QByteArray会更加方便。

四、注意事项

  实际应用中很可能出现QTextCodec* GBK = QTextCodec::codecForName("GBK");返回值为空的情况,这是因为QT需要手动加载中文编码插件。在QT的安装路径下找到plugins\codecs,将下面的qcncodecsd4.dll和qcncodecs4.dll拷贝到项目路径下的plugins\codecs下面,并在代码中添加到项目的libPath(注意路径只需要指定到plugin不需要指定到codecs哦)

QString pluginPath = QApplication::applicationDirPath()+"/plugin/";
QApplication::addLibraryPath(pluginPath);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值