Qt5之中文字符串转换

一、简介

在Qt开发过程中,从linux获取的中文字符串很容易出现乱码,linux创建的文件取决于不同的工具,有可能是GBK格式,有可能是UTF-8。所以需要一个通用的方式把中文转成正常的字符串显示出来。

Qt处理中文的方式:

编码类型 适用场景 Qt 中对应的解析方式
DOS 中文 DOS 环境下的文本 / 数据 GBK/GB2312(属于 Windows Local8Bit)
Windows 本地编码 系统默认 ANSI 编码 QString::fromLocal8Bit()
Qt 内部编码 字符串存储(无乱码) UTF-16(无需关心,Qt 自动处理)
UTF-8(通用) 跨平台推荐 QString::fromUtf8()
二、详解
1、 确认源数据的真实编码

(1)打印源字符串的十六进制数,对比编码表判断真实编码

复制代码
#include <QDebug>
#include <QTextCodec>

// 打印字节数组的十六进制(用于判断编码)
void printHex(const QByteArray &data) {
    QString hexStr;
    for (char c : data) {
        hexStr += QString("%1 ").arg(static_cast<unsigned char>(c), 2, 16, QChar('0'));
    }
    qDebug() << "源数据十六进制:" << hexStr.trimmed();
}
中文 GBK (CP936) 十六进制 UTF-8 十六进制 DOS CP850(无中文,仅西文)
你好 B0 A1 C4 E3 E4 BD A0 E5 A5 BD 无对应(显示乱码符号)
张三 D5 C5 C8 FD E5 BC A0 E4 B8 89 无对应
2、 复用的 Qt 通用编码转换代码

调用autoConvertToWindows即可获取转换后的中文

复制代码
bool hasValidChinese(const QString &text)
{
    // 匹配中文Unicode区间:[\u4e00-\u9fa5]
    return text.contains(QRegExp("[\\u4e00-\\u9fa5]"));
}

bool isCompleteGbk(const QByteArray &data)
{
    int len = data.length();
    if (len % 2 != 0) { // GBK中文必为2字节,奇数长度=截断
        qWarning() << "GBK字节流不完整:长度为奇数(" << len << "),可能截断";
        return false;
    }
    // 校验每个GBK字符的高位字节范围(GBK高位:0x81-0xFE)
    for (int i = 0; i < len; i += 2) {
        unsigned char high = static_cast<unsigned char>(data[i]);
        if ((high<0x81) || (high>0xFE)) {
            return false;
        }
    }
    return true;
}

QString autoConvertToWindows(const QByteArray &dosData)
{
    // 1. 先尝试GBK/CP936(最常见的DOS中文编码)
    QTextCodec *gbkCodec = QTextCodec::codecForName("CP936");
    if (!gbkCodec) {
        gbkCodec = QTextCodec::codecForLocale();
    }
    QString text = gbkCodec->toUnicode(dosData);

    // 2. 验证转换结果是否为有效中文(避免乱码)
    if (hasValidChinese(text) && isCompleteGbk(dosData)) { // 包含中文字符,转换成功
        return text;
    }

    // 3. 尝试UTF-8(误判为DOS编码的情况)
    text = QString::fromUtf8(dosData);
    if (hasValidChinese(text)) {
        return text;
    }

    // 4. 尝试DOS CP850转GBK
    QTextCodec *cp850Codec = QTextCodec::codecForName("CP850");
    if (cp850Codec) {
        QString unicodeText = cp850Codec->toUnicode(dosData);
        text = QString::fromLocal8Bit(unicodeText.toLocal8Bit());
        if (hasValidChinese(text)) {
            return text;
        }
    }
    text = QString::fromLocal8Bit(dosData);
    return text;
}
四、总结

上述代码经过不断添加格式解析,覆盖 DOS(CP850/CP437)、Windows 本地编码(GBK/CP936)、UTF-8 所有场景。自动识别源编码并转换为 Windows 可正常显示的 Qt 字符串,解决Qt中各类中文乱码问题。

相关推荐
灯澜忆梦1 小时前
GO_并发编程---定时器
开发语言·后端·golang
-银雾鸢尾-2 小时前
C#中的StringBuilder相关方法
开发语言·c#
-银雾鸢尾-2 小时前
C#中结构体与类的区别;抽象类与接口的区别
开发语言·c#
大模型码小白3 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
段一凡-华北理工大学5 小时前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
Ljwuhe5 小时前
C++——多态
开发语言·c++
心平气和量大福大6 小时前
C#-WPF-Window主窗体
开发语言·c#·wpf
从零开始的代码生活_7 小时前
C++ 继承详解:访问控制、对象模型、菱形继承与设计取舍
开发语言·c++·后端·学习·算法
云小逸7 小时前
【C++ 第七阶段:模板、泛型编程与工程综合详解】
开发语言·c++
Quz8 小时前
QML 信号与槽:直接绑定与跨文件通信
qt·编程语言·设计