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_TEXTCODEC
    QTextCodec *localeCodec = QTextCodec::codecForLocale();
    if (localeCodec)
        return localeCodec->fromUnicode(string);
#endif // QT_NO_TEXTCODEC
    return 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 QTextCodec
    QTextCodec::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;
}

测试结果 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity类银河恶魔城学习记录9-1 9-2 P89,90 Character stats - Stat script源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Stat.cs using System.Collections; using System.Collections.Generic; us…

迷茫了!去大厂还是创业?

大家好&#xff0c;我是麦叔&#xff0c;最近我创建了一个 学习圈子 有球友在 星球 里提问。 大厂的layout岗位和小厂的硬件工程师岗位&#xff0c;该如何选择&#xff1f; 这个问题我曾经也纠结过&#xff0c;不过现在的我&#xff0c;I am awake&#xff01; 肯定是有大点大。…

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…

Python 导入Excel三维坐标数据 生成三维曲面地形图(面) 4-4、线条平滑曲面(修改颜色)去除无效点

环境和包: 环境 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 fr…

Hyperopt自动化调参工具实践-1

hyperopt Hyperopt的任务是在一组可能的参数上找到标量值的最佳值&#xff0c;该标量值可能是随机的。 与许多优化包假定这些输入来自向量空间不同&#xff0c;Hyperopt是不同的&#xff0c;因为它鼓励使用者更详细地描述搜索空间。通过提供关于函数定义在哪里以及认为最佳值…

【办公类-40-02】20240311 python模仿PPT相册功能批量插入照片,更改背景颜色 (家长会系列二)

作品展示——用Python插入PPT相册 背景需求&#xff1a; 马上就要家长会&#xff0c;我负责做会议前的照片滚动PPT&#xff0c;通常都是使用PPT的相册功能批量导入照片&#xff0c; 生成给一个新的PPT文件 更改背景颜色 设置4秒间隔&#xff0c;应用到全部 保存&#xff0c;改…

迷茫的时候怎么办?

迷茫的时候怎么办&#xff1f;这是一个让无数人感到困惑的问题。当我们感到迷茫时&#xff0c;我们可能会感到无所适从&#xff0c;不知道该往哪个方向前进。这种情况并不罕见&#xff0c;尤其是在我们年轻的时候。我们可能会感到有许多事情要做却不知如何选择&#xff0c;同时…

java-数据结构—树

目录 树的组成 节点 度 根节点 其他组成部分 二叉树 普通二叉树 二叉查找树 二叉树的遍历 前序遍历 中序遍历 后序遍历 层序遍历 总结 平衡二叉树 平衡二叉树的旋转机制 左旋 右旋 需要旋转的四种情况 左左 左右 右右 右左 总结 红黑树 树的组成 节点…

【JAVA】我和“JAVA“的细水长流,输入输出

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-Ck59fYFNNdpuGmVT {font-family:"trebuchet ms",verdana,arial,sans-serif;f…

334.递增的三元子序列

题目&#xff1a;给你一个整数数组 nums &#xff0c;判断这个数组中是否存在长度为 3 的递增子序列。 如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k &#xff0c;使得 nums[i] < nums[j] < nums[k] &#xff0c;返回 true &#xff1b;否则&#xff0c;…

Docker 快速入门实操教程ER(完结)

Docker 快速入门实操教程&#xff08;完结&#xff09; 如果安装好Docker不知道怎么使用&#xff0c;不理解各个名词的概念&#xff0c;不太了解各个功能的用途&#xff0c;这篇文章应该会对你有帮助。 前置条件&#xff1a;已经安装Docker并且Docker成功启动。 实操内容&…

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

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

52、WEB攻防——通用漏洞弱口令安全服务协议web应用

文章目录 web类——加密&验证码后台服务类——SSH&RDP远程终端猜解应用类——zip&word文件压缩猜解 弱口令没有严格的定义&#xff0c;通常认为容易被别人猜测到或被破解工具破解的口令均为弱口令&#xff0c;通常与管理的安全意识和平台的初始化配置等相关&#x…

开发指南005-前端配置文件

平台要求无论前端还是后端&#xff0c;修改配置可以直接用记事本修改&#xff0c;无需重新打包或修改压缩包里文件。就前端而言&#xff0c;很多系统修改配置是在代码里修改&#xff0c;然后打包或者是修改编译环境来重新编译。 平台前端的配置文件为/static/js/下qlm_config.j…

Day36:安全开发-JavaEE应用第三方组件Log4j日志FastJson序列化JNDI注入

目录 Java-项目管理-工具配置 Java-三方组件-Log4J&JNDI Java-三方组件-FastJson&反射 思维导图 Java知识点&#xff1a; 功能&#xff1a;数据库操作&#xff0c;文件操作&#xff0c;序列化数据&#xff0c;身份验证&#xff0c;框架开发&#xff0c;第三方库使用…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《计及台区资源聚合功率的中低压配电系统低碳优化调度方法》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

第六套CCF信息学奥赛c++ CSP-J认证初级组 中小学信奥赛入门组初赛考前模拟冲刺题(选择题)

第六套中小学信息学奥赛CSP-J考前冲刺题 1、IPv4中,以下P地址不合法的是 A、255.255.255.255 B、0.1.1.1 C、1.1.1.0 D、1.0.0.0 答案&#xff1a;B 考点分析&#xff1a;主要考查网络相关知识&#xff0c;合法的IPv4地址第一个八位二进制必须是从1开始&#xff0c;到255…

RabbitMQ详解与常见问题解决方案

文章目录 什么是 RabbitMQ&#xff1f;RabbitMQ 和 AMQP 是什么关系&#xff1f;RabbitMQ 的核心组件有哪些&#xff1f;RabbitMQ 中有哪几种交换机类型&#xff1f;Direct Exchange(直连交换机)Topic Exchange(主题交换机)Headers Exchange(头部交换机)Fanout Exchange(广播交…

vscode设置setting.json

{ // vscode默认启用了根据文件类型自动设置tabsize的选项 "editor.detectIndentation": false, // 重新设定tabsize "editor.tabSize": 2, // #每次保存的时候自动格式化 // "editor.formatOnSave": true, // #每次保存的时候将代码按eslint格式…

Linux操作系统Makefile基本语法

一、Makefile规则格式 目标.....: 依赖文件集合.......命令1命令2..... main : main.o input.o calcu.ogcc -o main main.o input.o calcu.o 这条规则的目标是 main,main.o、 input.o和 calcu.o是生成 main的依赖文件&#xff0c;如果要更新 目标 main&#xff0c;就必须先更…