最近工作压力太大,blog也逐渐荒废,怎么也得写点东西了,要不说不过去。。。。。
Qt为字节流和字符串分别提供了QByteArray和QString两个类(还有QLatin1String等其他类,但这两个是最主要的)。当我们涉及到I/O时,比如读写文件、读写网络socket、控制台输入输出、读写串口… 操作的都是字节流,如果我们此时需要操作的内容是字符串,则需要二者之间的相互转换。在C和C++中,我们一般都是将 “Hello World!” 这种称为字符串。但是就目前而言,当我们提字符串时,一般是指一个Unicode字符串,其由一个一个的Unicode字符构成;当我们提字节流时,是指一个一个的字节。或许我们可以说,ANSI C/C++截止目前只有字节流,而缺乏对字符串的支持。另外各个编译器对编码的支持又严重不一, Qt为解决这个问题提供了QTextCodec。
QTextCodec * textc = QTextCodec::codecForName("GBK"); 1.QTextCodec::setCodecForCStrings(textc); 2.QTextCodec::setCodecForTr(textc); 3.QTextCodec::setCodecForLocale(textc);
QString 是不存在中文支持问题的,很多人遇到问题,并不是本身 QString 的问题,而是没有将自己希望的字符串正确赋给QString。很简单的问题,”我是中文”这样写的时候,它是传统的char 类型的窄字符串,我们需要的只不过是通过某种方式告诉QString 这四个汉字采用的那种编码。而问题一般都出在很多用户对自己当前的编码没太多概念。另外文件是有编码的,但是这种纯文本文件却不会记录自己采用的编码,这个是问题的根源。真的是 QString 乱码了吗?其实很简单的一个问题,当你从窄字符串 char* 转成Unicode的QString字符串的时候,你需要告诉QString你的这串char* 中究竟用的是什么编码?GBK、BIG5还是Latin-1。理想情况就是:将char* 传给QString时,同时告诉QString自己的编码是什么;但是QString 提供的成员函数,远远满足不了大家的需求,于是只有采取语句1的办法。
tr(“中文”);与QString(“中文”);一样,你必须告诉tr这个窄字符串是何种编码?你不告诉它,它就用latin1。于是所谓的乱码问题就出来了。如何告诉tr你写的这几个汉字在磁盘中保存的是何种编码呢?这正是语句2所做的。如果你的编码采用的utf8,可以直接使用trUtf8而不必设置setCodecForTr()。
对于语句3应该没什么好说的,在绝大多数情况下,我们在代码中应该都用不到这个函数(默认的system应该比我们所能设置的要好)。
下面讲一下关于编码转换问题:
QT中的QString内容使用Unicode作为文本编码。但是实际系统中通常采用的是其他编码,例如GBK,utf8等。为了便于兼容这些格式,QT中还设置了两个字符串类型:
QCString类: C类型字符串,必须以\0结尾,也就是中间不能含有\0. 例如GBK编码的字符串
QByteArray类: 中间可以含有\0.例如utf8编码的字符串
在设置下面的代码基础上:
QTextCodec *gbk = QTextCodec::codecForName("gb18030"); QTextCodec *utg8 = QTextCodec::codecForName("utf-8"); QTextCodec::setCodecForTr(gbk); QTextCodec::setCodecForLocale(gbk); QTextCodec::setCodecForCStrings(gbk);
1. UTF-8 转换 GBK
QString U2G(QString utfStr) { return gbk->toUnicode(utfStr.toLocal8Bit()); }
2 GBK 转换 UTF-8
QString U2G(QString gbkStr) { return utg8->toUnicode(gbkStr.toUtf8()); }
代码示例:
———————————————————————————–
QTextCodec *gbk = QTextCodec::codecForName("gb18030"); QTextCodec *utf8 = QTextCodec::codecForName("utf-8"); QTextCodec::setCodecForTr(gbk); QTextCodec::setCodecForLocale(gbk); QTextCodec::setCodecForCStrings(gbk); QFile file("../test.txt"); file.open(QIODevice::ReadOnly); QByteArray readByte = file.readAll(); QString readStr = utf8->toUnicode(readByte.data()); file.close(); QString utfStr = QObject::trUtf8(readByte); //utf-8 QString gbkStr = QObject::tr("中文"); // gbk QString utf2gbk = gbk->toUnicode(readStr.toLocal8Bit()); // utf8 conver gbk QString gbk2utf1 = utf8->toUnicode(utf2gbk.toUtf8()); // gbk convert utf8 QString g2u = gbk->toUnicode(gbk->fromUnicode(readStr)); // gbk convert utf8 qDebug() << "gbk:" << gbkStr; qDebug() << "utf8:" << utfStr; qDebug() << "readStr:" << readStr; qDebug() << "read_size:" << readByte.length(); qDebug() << "utf2gbk:" <<utf2gbk << "length:" << readStr.toLocal8Bit().length(); qDebug() << "gbk2utf8-1:" << gbk2utf1 << " length: " << utf2gbk.toUtf8().length(); qDebug() << "g2u" << g2u << "length:" << gbk->fromUnicode(utfStr).length(); QLabel *label = new QLabel(utf2gbk); label->show();
参考:
【1】http://www.cnblogs.com/bingcaihuang/archive/2011/03/17/1986714.html