记录下在做小学期项目时遇到问题的解决方案。我的开发环境是vs2019+MYSQL+QT。
这次遇到的问题是这样的:在向MYSQL中读取和写入数据时,无论含不含中文,都不会有乱码,但是向QT中写入和读取字符串时含中文会出现问题。在网络上找了一些解决方案,没有成功,研究了一天,解决了这个问题。
首先是写入的问题。一般存在于向控件中(Label,pushbutton)写入内容。
设置pushbutton点击事件,点击时设置按钮文字为“啦啦啦”
点击按钮,按钮的文字应该会发生变化
点击运行,结果如下
并没有出现设置的“啦啦啦”,而是出现了乱码
通过NotePad++打开vs2019中的文件,发现是以UTF-8形式的编码
所以我们在设置控件内容时应该告诉QString我们传入的字符串(通常是char*)是以UTF-8格式编码,而QString就自带了这个函数
利用QString(u8"")把char[]转换为QString类型
修改后运行结果如下
显示成功
这里在介绍另一个函数
这种方式便于传入字符串的变量,适用性更广
接下来是解决读取QString出现乱码和无法显示的问题。
如果直接从控件中读取内容并使用printf打印出来,
直接使用printf打印,先忽略警告
这会出现如下问题
明明输入内容,而且光标移动了,但是没有显示字符
上网查询,可知QString与c/c++中的字符串的区别:
C++语言提供了两种字符串的实现:C风格的字符串,以'\0‘结尾;std::string,即标准模版库中的类。Qt则提供了自己的字符串实现:QString,QString不用担心内存分配以及关于'\0'结尾的这些注意事项。
另外,与C风格的字符串不同,QString中间是可以包含'\0'符号的,而length()函数则会返回整个字符串的长度,而不仅仅是从开始到'\0'的长度。
所以如果以c/c++的字符串形式直接打印QString类型的字符串,因为缺少'\0',无法判断在哪里结束。
su所以我们只需要给QString字符串末尾加入'\0'就可以了?试一下。
QString::toLatin1()会在字符串后面加上'\0';
程序源码,把lineEdit控件中的内容结尾加上'\0',然后打印出来
运行查看结果
好像成功了
但是输入中文后发现打印出来的都是问号
上网查了一下这个问题,发现解决此问题有两个方法。
第一个是
先利用QString的toStdString函数转换为string类型,然后再用string类型的tc_str()函数转换为char*.代码如下
运行下查看结果
依旧是乱码
另一个方法是在代码前加入下面几行代码:
QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"))
但是这几个函数在QT5被废止了,不能使用。
联想这几个函数的使用的目的,是为了设置QT的编码,所以我们可以写一个函数转换字符串的编码方式。
我的vs2019是UTF-8而QT是GBK,所以我的做法是先把字符串从UTF8转到GBK,然后在再末尾加上'\0';
代码如下:
QString UTF82GBK(const QString& inStr)
{
QTextCodec* gbk = QTextCodec::codecForName("GB18030");
QTextCodec* utf8 = QTextCodec::codecForName("UTF-8");
QString utf2gbk = gbk->toUnicode(inStr.toLocal8Bit());
return utf2gbk;
}
char* QstringToChar(QString qstr)
{
qstr = UTF82GBK(qstr);
char* chStr = NULL;
QByteArray ba = qstr.toLocal8Bit();
chStr = (char*)malloc(sizeof(char) * 1000);
memset(chStr, 0, ba.length());
memcpy(chStr, ba.data(), ba.length());
chStr[ba.length()] = '\0';
return chStr;
}
直接调用上面所写的QStringToChar函数
运行查看结果
中英文都没问题
(学术水平有限,只是想分享下遇到问题的解决方案,如果有错请私信指正)