编辑器编码为GBK,简单打印一句中英文,在嵌入式中运行,串口控制台编码也是GBK,结果却是乱码
接着尝试把编辑器编码改为UTF-8,重新构建,却并不会编译!即qmake视之未改变。
同时把xshell编码改成UTF-8,即可正常显示中文。
此时得出结论编辑器调整编码对程序打印中文没有影响。
QT设置编码的语句如下所示:
QTextCodec *GBK = QTextCodec::codecForName("GBK"); //设置编码格式为GBK
QTextCodec::setCodecForCStrings(GBK);
QTextCodec::setCodecForTr(GBK);
QTextCodec::setCodecForLocale(GBK); //从QT5之后只剩这一句可用
QString str1("你好Hello");
QByteArray local = str1.toLocal8Bit();
其实Qt默认会使用本机编码,所以对于中文系统,第一句设置有时候是多余的(Windows下设置GBK是多余的,Linux下设置UTF-8是多余的)
它用于设置本机编码格式,但要配合Qstring的toLocal8Bit()方法转换为QByteArray 类型,才能得到GBK编码的数据,如line6-7所示。
显然我们不止一种to开头的转换方法,实际上有这么多:
不过这些也不全是转换字符串格式的方法,下面介绍另外两种格式转换方法:
QByteArray local = str1.toLocal8Bit(); //受setCodecForLocale影响,强制转换为GBK编码
printf("%s\n",local.data());
QByteArray Latin1 = str1.toLatin1(); // 不受setCodecForLocale影响,强制转换为ISO-8859-1编码
printf("%s\n",Latin1.data());
QByteArray Utf8 = str1.toUtf8(); // 不受setCodecForLocale影响,强制转换为UTF-8编码
printf("%s\n",Utf8.data());
UTF-8下输出:
ţºello
??Hello
你好Hello
GBK下输出:
你好Hello
??Hello
浣犲ソHello
可以看到格式真的转换了,于是Qstring到QByteArray的转换被我们打通了。
QTextCodec *GBK = QTextCodec::codecForName("GBK"); //设置编码格式为GBK
QTextCodec *UTF8 = QTextCodec::codecForName("utf-8");//设置编码格式为UTF-8
QByteArray ba1 = "你好Hello";//此时还是UTF8
/*局部编码转统一码Unicode*/
QString str2 = GBK->toUnicode(local);//GBK编码的ByteArray强制转换为unicode编码的QString 注意local一定得是GBK编 码,否则转换结果会出错
printf("%s\n",str2.toStdString().data()); //这里的Unicode编码其实就是UTF-8 与QT编辑器相关
QString str3 = UTF8->toUnicode(ba1);// 注意bal一定得是UTF-8编码
printf("%s\n",str3.toStdString().data()); //Unicode编码
/*统一编码转局部编码*/
ba1 = GBK->fromUnicode(str2);//把Unicode转成GBK,这里的str2一定得是Unicode编码
printf("%s\n",ba1.data());
ba1 = UTF8->fromUnicode(str3);//str3同理
printf("%s\n",ba1.data());
UTF-8下输出:
你好Hello
你好Hello
ţºello
你好Hello
GBK下输出:
浣犲ソHello
浣犲ソHello
你好Hello
浣犲ソHello
可以看到确实转换了,最终QByteArray到Qstring的转换也被我们打通了
QString是专门用来处理字符串的,除了能处理ASCII编码字符,还包括各国语言的编码,默认情况下QString会把所有数据当做utf-8编码来处理。QByteArray只是单纯用来处理数据的,除了能处理ASCII编码字符,其它复杂的编码不能处理,直接以字节流的方式来对待。
QString str("小马哥");
QByteArray byte("小马哥");
qDebug() << "str:" << str << "byte:" << byte << endl;
printf("%s\n",byte.data());
printf("%s\n",str.toStdString().data());
输出:
str: "小马哥" byte: "\xE5\xB0\x8F\xE9\xA9\xAC\xE5\x93\xA5"
小马哥
小马哥
这里也描述了打印两种类型变量的方法。
QByteArray temp1 = str1.toLocal8Bit();
printf("%p\n",temp1.data());
temp1 = str2.toLocal8Bit();
printf("%p\n",temp1.data());
temp1 = str3.toLocal8Bit();
printf("%p\n",temp1.data());
temp1 = str4.toLocal8Bit();
printf("%p\n",temp1.data());
输出:
0xbab1b0
0xbab010
0xbab1b0
0xbab010
这里str1-4是四个不同的QString,我们把它们转换成GBK后打印地址(因为调用data方法返回char*类型的指针,且带有停止符)
可以看到地址只有两种,如果稍作修改,不再共用一个QByteArray
QByteArray temp1 = str1.toLocal8Bit();
printf("%p\n",temp1.data());
QByteArray temp2 = str2.toLocal8Bit();
printf("%p\n",temp2.data());
QByteArray temp3 = str3.toLocal8Bit();
printf("%p\n",temp3.data());
QByteArray temp4 = str4.toLocal8Bit();
printf("%p\n",temp4.data());
输出:
0x181a1a0
0x181a000
0x181a020
0x181a040
可以看到不再共用一个地址,因此为了节省空间就要用前一种方法。