关于QString的乱码

千梦一生 2020-09-25 11:52:58
现在是Qt vc编译器。
大概流程如下:

<1> QString str = 输入的gbk编码字符串,例如“原始gbk字符串”;//无特殊转换直接输入

后面str作为参数传入函数
<2> setText(str)乱码

原因是在程序运行到<1>时,将"原始gbk字符串"默认为utf8进行解码。那么识别到的文字错误乱码是可以理解的。

但现在问题是:

在第二步<2>此时有没有办法将str还原为"原始gbk字符串"然后显式在窗口上【不用说在<1>那里QString::from编码()这个,这个我知道】。

尝试了几种变换,我发现,有点问题。
我怀疑在<1>赋值、或者说构造初始化时,是否str并不会获得并保存“原始gbk字符串”的原始编码。
因为我的乱码显式为???直接进行toGBK会答应为锟斤拷。似乎原始编码要么丢了,要么被改了?

希望论坛的朋友能为我解惑,谢谢。
...全文
39844 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
千梦一生 2021-03-29
  • 打赏
  • 举报
回复
大家的讨论和恢复都很有意义。我这里结帖姑且以大家写的字的长度计算分配了。见谅、谢谢。
千梦一生 2021-03-29
  • 打赏
  • 举报
回复
感谢各位老师、前辈的帮助。 实不相瞒这个帖子当初看了前几楼的回答未及时结帖【为了多看看大家对这个问题的看法】 但再后来给忘了,主要是很久没登陆csdn。 这个编码这个看楼上有几位提供的一个办法说:将源代码保存为UTF-8可以解决。 但在我之前学习了解后认为:这个方案对结果没有影响。【许久前的问题,记不得是否有做试验】【 因为vs编译器不是不能识别utf-8的字符。而是其在编译时期自作聪明将源码中的"中文"擅自更改为了gbk编码的字符存放在目标文件中、或者说exe中【如果这里能干预的话,像楼上所说指定编译器编译时的编码方式也是可以解决该问题的】。 程序执行时,在执行到str = QString("中文")代码时,默认相当于QString::fromutf8("中文")但此时其实际的编码是被vc编译出来的gbk的硬编码。所以相当于在构造函数时就翻车了。 当时认为虽然如此,只要其原始的在exe中的硬编码还保存在QString中的话,那么理论上看是完全可以转换回去的。 但当时尝试在setText函数内部对str进行.toGBK得到的却是:锟斤拷...很显然这意味着在str = QString("中文")时,utf8编码表中不存在gbk"中文"的编码,所以转换成了锟斤拷的编码。 】 另外楼上几位前辈关于中文字符的处理方案是值得我后来实践中学习的。 目前看来我认为:问题在str = QString("中文")构造时即已经出现,后来setText(str)函数中,面对的是一个非期望的输入,那么其输出应当是无效的
franzhong 2020-12-23
  • 打赏
  • 举报
回复
QT使用的utf-8,存诸时还会转换为utf-16的,你说的看乱码应该源码丢了,转码是可逆的,合适的方式是可以转回去的,乱码只是因为人看不懂而以,对于计算机不是乱码,QT中你也可以指定codec为utf-8,如果是文件中还有bom头问题,local与系统相关,windows一般gbk没问题的。读取时候试试fromLocal8Bit与QStringLiteral 你的问题 工具=》选项=》文本编辑器=》行为=》编码utf-8 、bom:如果是就添加 tr只是返回翻译版本,如果没有等同 QString::fromUtf8

ui->ipt_name->setText("我是中国人");//正常

QString str1 = "我是中国人1";
ui->ipt_name->setText(str1);//正常

QString str2 = QStringLiteral("我是中国人2");
ui->ipt_name->setText(str2);//正常

QString str3 = QString::fromLocal8Bit("我是中国人3");
ui->ipt_name->setText(str3);//乱码8位


qDebug()<<"###"<<"我是中国人4";//正常
qDebug()<< QString::fromUtf8("我是中国人5");//正常

亭台六七座 2020-12-15
  • 打赏
  • 举报
回复
QString::fromUtf8("中文");
hitzsf 2020-12-14
  • 打赏
  • 举报
回复
这总结的很到位了,差个 烫烫烫,屯屯屯
亭台六七座 2020-12-01
  • 打赏
  • 举报
回复
Yvette_QIU 2020-11-24
  • 打赏
  • 举报
回复
所以这算是结束了还是没结束呢?
D_KING_ 2020-10-14
  • 打赏
  • 举报
回复
tr接受QString,而QString默认构造编码为UTF-8,因此你那个老师胡说八道。 tr就是翻译用的,而不是用来解决编码问题。 楼上很多人提到QLatin1String、QStringLiteral,这两个类是优化性能用的,也并非解决编码问题。 而Qt将QString构造编码指定为UTF-8就不难找出乱码问题的解决方法。 1、将源代码保存为UTF-8编码格式。 2、在Linux系统中可以非常方便的将编译器编码指定为utf-8。 3、vs中可以添加以下编译器预处理代码以设定utf-8: #if defined(_MSC_VER)&&(_MSC_VER > 1700) #pragma execution_character_set("utf-8") #endif
  • 打赏
  • 举报
回复
引用 6 楼 丁劲犇 的回复:
Qt因为操作系统、编译器、编辑器环境不同,乱码问题确实复杂。这里试着和你解释下: 1、Linux 下,全部 UTF-8,一般不会有问题。即编辑器、编译器、操作系统全是UTF-8,代码中的汉字、UI文件汉字都能显示。 2、windows下,默认936,但又因为编译器不同,会有很多奇怪的事情。 (1) mingw编译器+QtCreator,全部默认UTF-8,一般不会有问题。即编辑器、编译器、操作系统全是UTF-8,代码中的汉字、UI文件汉字都能显示。 (2) VC IDE+VC编译器,代码默认是936的,编译时,还分 Unicode(16bit)和多字节字符(936)。这种行为导致winAPI本身都有宽窄版本。此时,若在代码中直接使用中文,就务必注意转换了。一般用 fromLocal8Bit转换。 (3) QtCreator+VC编译器,代码默认是UTF-8的,因此,使用 ::fromUTF-8 转换。 3、正确做法: 全部采用英文,在需要中文的地方,使用tr("")进行包裹。而后,添加翻译文件(.ts)后,在语言家翻译后跟随exe发布(*.qm)。也可以把翻译文件打包到资源文件里面一起发布。这个是一劳永逸解决所有乱码的高大上方法,且可以支持法文、德文、俄文、日文,做繁简切换。
编码显示的时候要统一。
  • 打赏
  • 举报
回复
上次听一个老师说,tr里面一般不包裹非英文的字符,Qt的本意是tr里是英文,而后翻译为别的文字。
qybao 2020-10-09
  • 打赏
  • 举报
回复
<1> QString str = 输入的gbk编码字符串
你源文件的编码是什么?如果不是gbk,这里就已经乱码了

在第二步<2>此时有没有办法将str还原为"原始gbk字符串"
你可以试试在<2>用QTextCodec的codecForName转回来试试,如果不行,还是在<1> 就保证编码一致吧
fly4free 2020-10-09
  • 打赏
  • 举报
回复
把下面代码(注释是我回帖好说明问题用的),放在一个头文件中,其他用到的文件就包含它

#include <QString>

#ifdef _MSC_VER
// MSVC (截止至VC2017, 2019没用过) 不管文件以什么编码存储,中文系统下都会转为GBK
#define _tr(x) QString::fromLocal8Bit(x)
#elif defined(__GNUC__) || defined(__MINGW32__)
//非 MSVC 编译器,代码文件要一般都会以 utf-8 编码存储,不是的话,就手动转换保存一下。
#define _tr(x) QString::fromUtf8(x)
// 编译器支持 C++11 的话
#define _trc(x) u8##x
#endif


QObject有 tr 方法 QObject::tr() ,但那个是为了本地化翻译而准备的,
我这里前面加了下划线仅仅是取个不要太长的名字,比如:QStringLiteral("a中文a") 就太长了……

如果你认为6楼提供的正确做法是大炮打蚊子的话,那么可以试试我的方法,加入上述代码后:

QString str = _tr("123中文abc");


而一般我在VC下,新建源码文件后,我会把其确保另存为 【Unicode (UTF-8 带签名) - 代码页 65001】编码格式的(我也不嫌麻烦……)
我就是这样,来写 Linux / Windows 兼容的代码项目的。
  • 打赏
  • 举报
回复
Qt因为操作系统、编译器、编辑器环境不同,乱码问题确实复杂。这里试着和你解释下:

1、Linux 下,全部 UTF-8,一般不会有问题。即编辑器、编译器、操作系统全是UTF-8,代码中的汉字、UI文件汉字都能显示。
2、windows下,默认936,但又因为编译器不同,会有很多奇怪的事情。
(1) mingw编译器+QtCreator,全部默认UTF-8,一般不会有问题。即编辑器、编译器、操作系统全是UTF-8,代码中的汉字、UI文件汉字都能显示。
(2) VC IDE+VC编译器,代码默认是936的,编译时,还分 Unicode(16bit)和多字节字符(936)。这种行为导致winAPI本身都有宽窄版本。此时,若在代码中直接使用中文,就务必注意转换了。一般用 fromLocal8Bit转换。
(3) QtCreator+VC编译器,代码默认是UTF-8的,因此,使用 ::fromUTF-8 转换。
3、正确做法:
全部采用英文,在需要中文的地方,使用tr("")进行包裹。而后,添加翻译文件(.ts)后,在语言家翻译后跟随exe发布(*.qm)。也可以把翻译文件打包到资源文件里面一起发布。这个是一劳永逸解决所有乱码的高大上方法,且可以支持法文、德文、俄文、日文,做繁简切换。
donwmufromdying 2020-09-28
  • 打赏
  • 举报
回复
搞对源代码的编码格式和可执行代码的编码格式。如果你一定要在你的源代码中直接中文常量字符串,那么你的源码编码格式就需要先确定好。然后要清楚转换的方式,任何编码的要首先转成unicode,然后再用对应的codec转成对应编码。 在你的pro文件中加上这两行: msvc:QMAKE_CXXFLAGS += -execution-charset:utf-8 msvc:QMAKE_CXXFLAGS += -source-charset:utf-8 根据你的实际情况去调整
qq_33487700 2020-09-28
  • 打赏
  • 举报
回复
请参考QTextCodex类中codecForName和toUnicode函数
蓝白云 2020-09-28
  • 打赏
  • 举报
回复
首先你的所有代码源文件最好统一为一种编码格式,然后在做编码转换,否则容易乱掉。
参考:https://blog.csdn.net/vivasoft/article/details/60868483
瞧缝 2020-09-28
  • 打赏
  • 举报
回复
QStringLiteral中文全部用这个包一下
hitzsf 2020-09-25
  • 打赏
  • 举报
回复
QLatin1String 试试这个类

16,814

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧