qt 汉字输出 中文输出 显示乱码 qDebug() 乱码 解决

要正确显示汉字,必须要先了解计算机文字编码相关知识,参考:unicode ucs2 utf16 utf8 ansi GBK GB2312 互转 及 渲染_ucs2编码转换-CSDN博客

1、汉字输出到 应用程序输出面板 

qt 自定义的输出类qDebug() 、QDebug对象、QMessageLogger默认输出到 应用程序输出面板 

当qt使用vs编译器时,对于输出到应用程序输出面板上时,给OutputDebugStringW()投喂unicode的utf-16编码的字符串,对于GB2312范围内的字符串是不会乱码的或出现文字遗失的。

当qt使用mingw编译器时,输出到应用程序输出面板上时,给OutputDebugStringW()投喂unicode的utf-16编码(双字节)的字符串,会被莫名其妙的按单个字节拆成unicode的utf16编码,暂时还没找到什么原因。比如"你好" ,utf16为0x4F60 0x597D,但是在选用Mingw编译器输出到output panel时显示成ÄãºÃ,对应的utf16编码为:0x00C4 0x00E3 0x00BA 0x00C3

 下面是两个可以直接显示到output panel 的windows api。加上<windows.h>就可以直接调用

    OutputDebugStringW(L"aaa你好"); //windows api,用于将utf16编码的字符串显示到output panel上OutputDebugStringA("aaa你好");  //windows api,用于将ansi编码的字符串显示到output panel上    

2、汉字输出到控制台窗口

qt自定义输出类QDebug类、qDebug()、QMessageLogger类、qt_message_output() 默认输出到到qt ide 的 应用程序输出面板 (application output panel)上,需要通过设置来输出到 控制台窗口

vs qt 调试 输出 打印 到 输出窗口 或 控制台窗口_qt输出信息到窗口-CSDN博客

控制台窗口显示正确的汉字需要很小心。

1、最基础的是要明确知道你投喂给控制台窗口的字符串是什么编码的。QString中字符串是以unicode的utf16编码进行保存的。当需要输出到控制台的时候,内部会通过QTextCodec进行转码,转成QTextCodec所设置的目标编码的字符串。然后再输出给控制台。

2、控制台只支持显示兼容ascii编码的编码方式,可以是ansi(GB2312),可以是utf8,但是不支持显示utf16编码。
控制台所支持的字体库有限,并且只能是GB2312字符集,对于超出的显示会乱码或两问号。具体原因比较复杂。
通过system("chcp 65001"); 设置控制台显示utf8编码的字符,通过system("chcp 936"),设置控制台显示GB2312编码的字符。

3、其次投喂给控制台的字符编码需要与控制台当前支持的编码要一致。在字符串前面加u8 ,强制字符串以utf8编码的方式存入到char*类型变量的内存中。这个无法强制QString,任何编码类型的字符串输入给QString保存,QString都会自动转码成utf16编码。如果需要可以使用QByteArray 或者QLatin1String进行保存。详细请参考:QString 与 字符编码 QTextCodec-CSDN博客 

4、QString或者 QTextCodec 提供了非常方便使用的文字编码转换接口。

另外QString向控制台输出的时候有一个toLocal8Bit()的过程。这是导致在控制台显示乱码的一个因素。如果使用qt自定义输出类及接口向控制台窗口输出,想要正确输出汉字,必须要指定正确的QTextCodec。QTextCodec默认为system,windows下为ansi,linux下为utf8。

D:\Qt\Qt5.12.0\5.12.0\Src\qtbase\src\corelib\global\qlogging.cpp
......
static void stderr_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &message)
{QString formattedMessage = qFormatLogMessage(type, context, message);// print nothing if message pattern didn't apply / was empty.// (still print empty lines, e.g. because message itself was empty)if (formattedMessage.isNull())return;fprintf(stderr, "%s\n", formattedMessage.toLocal8Bit().constData());fflush(stderr);
}
......D:\Qt\Qt5.12.0\5.12.0\Src\qtbase\src\corelib\tools\qstring.cpp
......
QByteArray QStringRef::toLocal8Bit() const
{return qt_convert_to_local_8bit(*this);
}
.....
static QByteArray qt_convert_to_local_8bit(QStringView string)
{if (string.isNull())return QByteArray();
#ifndef QT_NO_TEXTCODECQTextCodec *localeCodec = QTextCodec::codecForLocale();if (localeCodec)return localeCodec->fromUnicode(string);
#endif // QT_NO_TEXTCODECreturn qt_convert_to_latin1(string); //被当做ascii编码处理。
}
......

案例 

#include <QTextCodec>
#include <QDebug>
#include <Windows.h>
int main()
{//QTextCodec编码器要与编译器参数execution-charset(vs编译器,默认为GB2312)/fexec-charset(gcc或类gcc编译器,默认为UTF8)的值一致,QTextCodec *codec=QTextCodec::codecForName("GB2312");   //设置QString的fromLocal8Bit() 和toLocal8Bit()的QTextCodec为GB2312QTextCodec//QTextCodec *codec=QTextCodec::codecForName("UTF-8");  //设置QString的fromLocal8Bit() 和toLocal8Bit()的QTextCodec为UTF-8 QTextCodecQTextCodec::setCodecForLocale(codec);QString s=QString::fromLocal8Bit("你好");//QString s=QString::fromUtf8(u8"你好");  //system("chcp 936");      //设置控制台输出窗口接收GB2312编码的字符串//system("chcp 65001");  //设置控制台输出窗口接收utf8编码的字符串qDebug()<<s<<endl;return 0;
}

3、编译器坑

vs2015编译器,需要更新 Visual Studio 2015 Update 2,才能支持下面两个选项。

下面两个参数告知编译器输入文件编码 及 告诉编译器将字符串保存到内存中使用的编码。

//gcc 或 类gcc编译器
QMAKE_CXXFLAGS += -finput-charset=UTF-8
QMAKE_CXXFLAGS += -fexec-charset=UTF-8
//vs编译器
QMAKE_CXXFLAGS += /source-charset:utf-8
QMAKE_CXXFLAGS += /execution-charset:utf-8

上面的参数不能混用 

//测试代码
#include <QDebug>
#include <QTextCodec>
#include <iostream>
using namespace std;int main(int argc, char *argv[])
{QTextCodec *codec = QTextCodec::codecForName("UTF-8");  //QTextCodec::setCodecForLocale(codec);//cout<<::getenv("path")<<endl;system("chcp 65001");cout<<u8"你好𬌗"<<endl;qDebug()<<"aa你好𬌗"<<endl;return 1;
}

测试结果 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/738426.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用眼精星票证识别系统,轻松将户口本转成结构化Excel

眼精星票证识别系统是一款革命性的软件&#xff0c;它以高度的精准性和效率为特点&#xff0c;为用户提供了一个简单便捷的工具&#xff0c;将纸质户口本转化为结构化数据。这一创新技术不仅改变了传统数据录入的方式&#xff0c;还大大提高了工作效率&#xff0c;为用户节省了…

Buildroot 之二 详解构建架构、流程、external tree、示例

构建系统 Buildroot 中的构建系统使用的是从 Linux Kernel(4.17-rc2) 中移植的 Kconfig(配置) + Makefile & Kbuild(编译)这套构建系统,移植后的源码位于 support/kconfig/ 目录下。Buildroot 本身是一个构建系统,与直接编译源码不同,因此,它对这套系统进行了比较…

web服务器集群试题

服务器IP地址规划&#xff1a;client&#xff1a;12.0.0.12/24&#xff0c;网关服务器&#xff1a;ens36:12.0.0.1/24、ens33&#xff1a;192.168.11.1/24&#xff1b;Web1&#xff1a;192.168.11.10/24&#xff0c;Web2&#xff1a;192.168.11.11/24&#xff0c;Nginx&#xf…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Stack容器组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之Stack容器组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Stack容器组件 堆叠容器&#xff0c;子组件按照顺序依次入栈&#xff0c;后一…

Yarn:Node.js依赖管理的现代选择

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

HTML5七天学会基础动画网页10(2)

制作立方体 学完前面的基础内容&#xff0c;制作立方体是个不错的练习方法&#xff0c;先看成品 再分析一下&#xff0c;六个面让每个面旋转平移就可以实现一个立方体&#xff0c;来看代码: <title> 制作立方体</title> <style> *{ margin: 0; padding: 0; …

Kotlin:枚举类

点击查看枚举类中文文档 点击查看枚举类英文文档 枚举类的最基本的用法是实现类型安全的枚举&#xff1a; enum class Direction {NORTH, SOUTH, WEST, EAST }每个枚举常量都是一个对象。枚举常量用逗号分隔。 初始化 因为每一个枚举都是枚举类的实例&#xff0c;所以他们可…

【HTML】div设为输入框,巧妙添加placeholder效果

效果图 文本撑满时 初始化时 码 contenteditable"true" 设为可编辑状态 <divcontenteditable"true"placeholder"评个小论吧&#xff01;"class"textarea"></div><style>/* 设置最小高度&#xff0c;超过滚动显示 …

Python 导入Excel三维坐标数据 生成三维曲面地形图(面) 3、线条平滑曲面但有条纹

环境和包: 环境 python:python-3.12.0-amd64包: matplotlib 3.8.2 pandas 2.1.4 openpyxl 3.1.2 scipy 1.12.0 代码: import pandas as pd import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from scipy.interpolate import griddata im…

操作系统:进程地址空间

目录 1.程序地址空间 1.1.程序地址空间的介绍 1.2.程序地址空间的本质 2.进程地址空间 3.Linux下的地址空间 1.程序地址空间 1.1.程序地址空间的介绍 我们在学习C/C时&#xff0c;对于各组分的地址分配在程序地址空间的不同模块 如图我们能够验证各组分的对应的地址排布位…

xss.haozi.me靶场“0x00-0x0A”通关教程

君衍. 一、靶场介绍二、第一关 0x00 不做限制三、第二关 0x01 文本闭合标签绕过四、第三关 0x02 双引号闭合绕过五、第四关 0x03 过滤括号六、第五关 0x04 编码绕过七、第六关 0x05 注释闭合绕过八、第七关 0x06 换行绕过九、第八关 0x07 删除标签十、第九关 0x08 多加空格绕过…

负数的四舍五入

负数的四舍五入 标签:基础 System.out.println(Math.round(-0.2)); System.out.println(Math.round(-0.5)); System.out.println(Math.round(-0.6));0 0 -1理解:四舍五入,找一个离目标小数近的整数,-0.2和0近,-0.6和-1近,中间的往右靠

力扣每日一题 将标题首字母大写 模拟 String API

Problem: 2129. 将标题首字母大写 文章目录 思路复杂度Code 思路 &#x1f468;‍&#x1f3eb; 灵神题解 复杂度 ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( n ) O(n) O(n) Code class Solution {public String capitalizeTitle(String title)…

重定向、管道与环境变量

前言&#xff1a;测试开发的学习已经开启第三周的学习了。 奋斗至此&#xff0c;内容已稍有难度。 发现每一点都有其深挖的地方&#xff0c;但读书在某些方面来讲要不求甚解&#xff0c;如果只在一点深挖&#xff0c;那可能进度很难提的上来。 继续加油&#xff01;&#xf…

es 分词器详解

基本概念 分词器官方称之为文本分析器&#xff0c;顾名思义&#xff0c;是对文本进行分析处理的一种手段&#xff0c;基本处理逻辑为按照预先制定的分词规则&#xff0c;把原始文档分割成若干更小粒度的词项&#xff0c;粒度大小取决于分词器规则。 分词器发生的时期 1、分词…

实现支持多选的QComboBox

Qt提供的QComboBox只支持下拉列表内容的单选&#xff0c;但通过QComboBox提供的setModel、setView、setLineEdit三个方法&#xff0c;可以对QComboBox进行改造&#xff0c;使其实现下拉列表选项的多选。 QComboBox可以看作两个组件的组合&#xff1a;一个QLineEdit和一个QList…

ctfshow web入门 php特性总结

1.web89 intval函数的利用&#xff0c;intval函数获取变量的整数值&#xff0c;失败时返回0&#xff0c;空的数组返回&#xff0c;非空数组返回1 num[]1 intval ( mixed $var [, int $base 10 ] ) : int Note: 如果 base 是 0&#xff0c;通过检测 var 的格式来决定使用的进…

【工具】Git的介绍与安装

目录 前言 1W&#xff1a;什么是Git&#xff1f; 2W&#xff1a;为什么使用Git&#xff1f; 3W&#xff1a;如何使用Git&#xff1f; Git的安装步骤 测试 3.1 桌面空白部分鼠标右击 3.2 选择 Open Git Bash here 3.3 输入 git -v 命令查看版本 Git区域分布 Git的工作…

软件无线电系列——软件无线电的发展历程及体系框架

本节目录 一、软件无线电的起始 二、软件无线电SDR论坛 三、SPEAKeasy计划 四、JTRS与SCA 五、软件无线电体系框架本节内容 一、软件无线电的起始 1992年5月&#xff0c;美国电信会议上&#xff0c;Joseph Mitola III博士提出来软件无线电(Software Radio,SR)的概念。理想化的…

Qt/QML编程之路:fork、vfork、exec、clone的对比及使用(46)

前言: 系统调用system call是OS提供的服务提供接口。系统调用fork()、vfork()、exec()和clone()都用于创建和操作进程。Linux下Qt编程也会用到vfork进行多进程间通信。让我们看一下以下每个系统调用的概述和比较: fork()、vfork()和clone()的工作原理相似,但在处…