Qt中QFile类读取ansi编码格式txt文件,在QTextEdit控件中显示乱码

news2024/11/9 9:48:27

系列文章目录

文章目录

  • 系列文章目录
  • 前言
  • 一、依然无法解决乱码问题
  • 二、解决办法
    • 1.方法一:使用QString的fromLocal8Bit()函数
    • 2.读取utf-8编码格式的文件
  • 总结

前言

使用Qt中的QFile类读取ANSI编码格式的文本文件,并在QTextEdit控件中显示乱码,这可能是由于编码问题导致的。QFile类默认使用系统的本地编码来读取文件,而ANSI编码通常与系统的本地编码不同。

为了正确地读取ANSI编码的文本文件并在QTextEdit控件中显示,你可以使用QTextCodec类来指定正确的编码。以下是一个示例代码片段,演示了如何读取ANSI编码的文本文件并在QTextEdit控件中显示正确的文本:

#include <QApplication>
#include <QFile>
#include <QTextStream>
#include <QTextCodec>
#include <QTextEdit>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    // 创建QTextEdit控件
    QTextEdit textEdit;

    // 读取ANSI编码的文本文件
    QFile file("path_to_your_file.txt");
    if (file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        // 使用ANSI编码创建QTextCodec对象
        QTextCodec *codec = QTextCodec::codecForName("Windows-1252");

        // 使用指定的编码创建QTextStream对象
        QTextStream stream(&file);
        stream.setCodec(codec);

        // 读取文本文件内容
        QString content = stream.readAll();

        // 在QTextEdit控件中显示文本
        textEdit.setPlainText(content);

        // 关闭文件
        file.close();
    }

    // 显示窗口
    textEdit.show();

    return app.exec();
}

在这里插入图片描述

一、依然无法解决乱码问题

使用了Windows-1252编码(也称为ANSI编码)来创建了一个QTextCodec对象,并将其应用于QTextStream,以便正确解码文件内容。然后,我们将解码后的文本内容设置为QTextEdit控件的文本。使用utf8依然无法解决乱码问题,

void ProjectWin::readParaFile(QString filePath)
{
    m_paraText->clear();
    if (!m_paraText) {
        qDebug() << "m_paraText is null!";
        return;
    }



    QString txtFile = filePath.left(filePath.size() -3);
    txtFile += "txt";
    QFile file(filePath);
    if(!file.open(QIODevice::ReadOnly)) {
        qDebug() << file.errorString();
    }

//    QByteArray fileData = file.readAll(); // 一次性读取整个文件内容
//    QString decodedText = QTextCodec::codecForName("UTF-8")->toUnicode(fileData); // 使用UTF-8解码
//    m_paraText->setPlainText(decodedText); // 设置文本内容

    QTextStream in(&file);
    in.setCodec("UTF-8");  // 设置编码为UTF-8
//    in.setCodec("GBK");  // 设置编码为GB18030
    QString chineseText;

//    QTextCodec* codec = QTextCodec::codecForName("UTF-8"); // 指定正确的文本编码
    while(!in.atEnd()) {
        QString line = in.readLine();
//        QByteArray utf8Data = line.toUtf8();
//        qDebug() << utf8Data.data();
//        line = line.trimmed(); //去掉2端字符串空格

//        emit appendText(line);  // 使用信号来添加文本

        if(line.contains(u8"任务代号:", Qt::CaseSensitive))
        {
            int pos = line.lastIndexOf(":");
            QString taskNum = line.right(line.size() - pos - 2);
            taskNum = taskNum.trimmed();
            m_taskNumSet.insert(taskNum);
//            break;
        }

//        m_paraText->setFont(QFont("Microsoft YaHei"));
//        m_paraText->setFont(QFont("Microsoft YaHei")); // 使用"Microsoft YaHei"字体

        m_paraText->append(line); // 添加到QTextEdit控件中
    }

    file.close();
}

二、解决办法

1.方法一:使用QString的fromLocal8Bit()函数

void ProjectWin::readParaFile(QString filePath)
{
    m_paraText->clear();
    if (!m_paraText) {
        qDebug() << "m_paraText is null!";
        return;
    }

    QString txtFile = filePath.left(filePath.size() -3);
    txtFile += "txt";
    filePath = "E:/work/ImageManageSys/utf8/0000_051623_162252_05_004_00001_00008_00.txt";
    QFile file(filePath);
    if(file.open(QIODevice::ReadOnly)) {
//        qDebug() << file.errorString();
        QTextCodec::setCodecForLocale(QTextCodec::codecForName("gb2312"));//中文转码声明
        QString temStr;
        while(!file.atEnd())
        {
                QByteArray arr = file.readAll();
                arr.replace(0x0B,0x0D);
                temStr = QString::fromLocal8Bit(arr, arr.length());//Window下的QByteArray转QString
                m_paraText->append(temStr);
        }

        //读取任务号
        while (!file.atEnd())
        {
           QString line = file.readLine();
           if(line.contains(u8"任务代号:", Qt::CaseSensitive))
            {
                int pos = line.lastIndexOf(":");
                QString taskNum = line.right(line.size() - pos - 2);
                taskNum = taskNum.trimmed();
                m_taskNumSet.insert(taskNum);
                break;
            }

        }
    }

    file.close();
}

这种方式读取ansi编码格式的txt文件可以正常显示,但是如果读取utf-8格式的txt文件反而是乱码,切记!切记!切记!重要的事说三遍。

2.读取utf-8编码格式的文件

void ProjectWin::readParaFile(QString filePath)
{
    m_paraText->clear();
    if (!m_paraText) {
        qDebug() << "m_paraText is null!";
        return;
    }



    QString txtFile = filePath.left(filePath.size() -3);
    txtFile += "txt";
    QFile file(filePath);
    if(!file.open(QIODevice::ReadOnly)) {
        qDebug() << file.errorString();
    }

//    QByteArray fileData = file.readAll(); // 一次性读取整个文件内容
//    QString decodedText = QTextCodec::codecForName("UTF-8")->toUnicode(fileData); // 使用UTF-8解码
//    m_paraText->setPlainText(decodedText); // 设置文本内容

    QTextStream in(&file);
    in.setCodec("UTF-8");  // 设置编码为UTF-8
//    in.setCodec("GBK");  // 设置编码为GB18030
    QString chineseText;

//    QTextCodec* codec = QTextCodec::codecForName("UTF-8"); // 指定正确的文本编码
    while(!in.atEnd()) {
        QString line = in.readLine();
//        QByteArray utf8Data = line.toUtf8();
//        qDebug() << utf8Data.data();
//        line = line.trimmed(); //去掉2端字符串空格

//        emit appendText(line);  // 使用信号来添加文本

        if(line.contains(u8"任务代号:", Qt::CaseSensitive))
        {
            int pos = line.lastIndexOf(":");
            QString taskNum = line.right(line.size() - pos - 2);
            taskNum = taskNum.trimmed();
            m_taskNumSet.insert(taskNum);
//            break;
        }

//        m_paraText->setFont(QFont("Microsoft YaHei"));
//        m_paraText->setFont(QFont("Microsoft YaHei")); // 使用"Microsoft YaHei"字体

        m_paraText->append(line); // 添加到QTextEdit控件中
    }

    file.close();
}

总结

在Qt中,QFile类本身并不提供直接获取文件编码格式的方法。文件编码是文件内容的属性,QFile只提供了对文件的读取和写入功能。要获取文件的编码格式,你可以使用其他的库或方法来分析文件内容并推断出编码格式。

一种常用的方法是使用第三方库如uchardet或libmagic来检测文件的编码。这些库可以通过分析文件内容的特征来猜测其可能的编码格式。你可以将文件内容读取到内存中,并使用这些库来进行编码检测。

以下是一个使用uchardet库来检测文件编码的示例:

在Qt项目中集成uchardet库,可以使用CMake或手动编译该库。
在Qt项目的代码中引入uchardet的头文件和链接库。
使用QFile读取文件内容,并将其传递给uchardet来检测编码格式。

#include <uchardet/uchardet.h>

QString detectFileEncoding(const QString& filePath)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << "Failed to open file:" << file.errorString();
        return QString();
    }

    QByteArray data = file.readAll();
    uchardet_t ud = uchardet_new();
    uchardet_handle_data(ud, data.constData(), data.size());
    uchardet_data_end(ud);
    const char* encoding = uchardet_get_charset(ud);
    QString detectedEncoding = QString::fromLatin1(encoding);
    uchardet_delete(ud);

    file.close();

    return detectedEncoding;
}

void ProjectWin::readFileAndDetectEncoding(const QString& filePath)
{
    QString detectedEncoding = detectFileEncoding(filePath);
    qDebug() << "Detected Encoding:" << detectedEncoding;

    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << "Failed to open file:" << file.errorString();
        return;
    }

    QTextStream in(&file);
    in.setCodec(detectedEncoding.toUtf8()); // 设置检测到的编码

    QString content = in.readAll();

    file.close();

    // 处理读取到的文件内容...
}

上述代码中的detectFileEncoding()函数使用uchardet库来检测文件的编码格式,并返回检测到的编码字符串。然后,在readFileAndDetectEncoding()函数中,使用检测到的编码来设置QTextStream的编码,以正确读取文件内容。

请注意,uchardet是一个独立的第三方库,并不随Qt自带。你需要在项目中引入并正确配置该库的构建和链接。

另外,需要注意的是,自动检测编码并不总是100%准确,特别是对于一些特殊或混合编码的文件,可能会有误判。因此,最好还是能够事先知道文件的准确编码格式,或者提前约定好文件的编码方式。

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

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

相关文章

适配器模式的运用

文章目录 一、适配器模式的运用1.1 介绍1.2 适配器模式结构1.3 类适配器模式1.3.1 类适配器模式类图1.3.2 代码 1.4 对象适配器模式1.4.1 对象适配器模式类图1.4.2 代码 1.5 应用场景1.6 JDK源码解析1.6.1 字节流到字符流的转换类图1.6.2 部分源码分析1.6.3 总结 一、适配器模式…

MyBatis的使用、Spring AOP、Spring事务

一、MyBatis 的使用 1、环境配置 1.1、建库建表 -- 创建数据库 drop database if exists mycnblog; create database mycnblog DEFAULT CHARACTER SET utf8mb4;-- 使⽤数据数据 use mycnblog;-- 创建表[⽤户表] drop table if exists userinfo; create table userinfo(id in…

智能算法终极大比拼,以CEC2017测试函数为例,十种智能算法直接打包带走,不含任何套路!

包含人工蜂群(ABC)、灰狼(GWO)、差分进化(DE)、粒子群(PSO)、麻雀优化(SSA)、蜣螂优化(DBO)、白鲸优化(BWO)、遗传算法(GA)、粒子群算法(PSO)&#xff0c;基于反向动态学习的差分进化算法&#xff0c;共十种算法&#xff0c;直接一文全部搞定&#xff01; 还是老规矩&#xff…

Android MaterialComponents主题下Button设置background无效

问题描述 使用的主题代码如下图&#xff1a; <!-- Base application theme. --><style name"Base.Theme.MyApplication" parent"Theme.Material3.DayNight.NoActionBar"><!-- Customize your light theme here. --><!-- <item na…

JAVA面向对象(二)

第二章 方法与方法重载 目录 第二章 方法与方法重载 带参方法的使用 构造方法 构造方法重载 成员变量和局部变量 总结 内容仅供学习交流&#xff0c;如有问题请留言或私信&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 有空您就点点赞 带参方法的使用…

Java代码的运行过程

我们来聊一聊java代码是如何运行的。大家都知道java是运行在JVM上的&#xff0c;那它是怎么结合操作系统去控制那些硬件设备的呢&#xff1f; 其实想要知道这个问题我们可以跟踪一行代码的整个生命周期来解释&#xff0c;我把它抽象为这么五个步骤。 首先这行代码会被编译成字节…

最强攻略 | 1分钟带你了解内测,成为BUG小能手!

「百度产品内测」招募内测体验官啦&#xff01;&#xff01; 参与百度内测&#xff0c;不仅可以直接接触百度运营官&#xff0c;还能拿礼物拿京东卡拿百度大礼包&#xff01; 什么你说你没接触过内测&#xff1f;贴心如我&#xff0c;给大家带来一份史上最全的新手入门指南&am…

​DMBOK知识梳理for CDGA/CDGP——第五章 数据模型与设计(附常考知识点)

关 注gzh“大数据食铁兽”&#xff0c;回复“知识点”获取《DMBOK知识梳理for CDGA/CDGP》常考知识点&#xff08;第五章 数据模型与设计&#xff09; 第五章 数据模型与设计 第五章是CDGA|CDGP考试的重点考核章节之一&#xff0c;分值占比高&#xff0c;知识点比较密集…

【大数据之路4】分布式计算模型 MapReduce

4. 分布式计算模型 MapReduce 1. MapReduce 概述1. 概念2. 程序演示1. 计算 WordCount2. 计算圆周率 π 3. 核心架构组件4. 编程流程与规范1. 编程流程2. 编程规范3. 程序主要配置参数4. 相关问题1. 为什么不能在 Mapper 中进行 “聚合”&#xff08;加法&#xff09;&#xff…

MATLAB入门教程||MATLAB决策制定||MATLAB if...end 语句

MATLAB决策制定 本节内容&#xff1a;了解MATLAB提供的决策类型&#xff0c;及使用它们进行决策制定。 决策结构用来做什么&#xff1f;决策结构要求程序员能够使用一个或者多个的条件来对程序进行评估或者测试&#xff0c;沿着一条或多条语句执行&#xff0c;如果该条件被确定…

docker启动rabbitmq无法访问15672端口

1.问题说明 使用rabbitmq:3.8.14版本启动了rabbitmq容器&#xff0c;5672、25672端口都可以连接&#xff0c;唯独15672仅在服务器本地可被连接。 2.问题原因 rabbitmq:3.8版本开始&#xff0c;管理插件包含在RabbitMQ发行版中。与其他任何插件一样&#xff0c;必须先启用它&am…

SpringCloud_微服务基础day2(Eureka简介与依赖导入,服务注册与发现)

p6:Eureka简介与依赖导入 前面我们了解了如何对单体应用进行拆分&#xff0c;并且也学习了如何进行服务之间的相互调用&#xff0c;但是存在一个问题&#xff0c;就是虽然服务拆分完成&#xff0c;但是没有一个比较合理的管理机制&#xff0c;如果单纯只是这样编写&#xff0c;…

实战:Spring Cloud Stream集成兼容多消息中间件kafka、rabbitmq

文章目录 前言实战要点技术积累Spring Cloud Stream简介集成kafka要点集成rabbitmq要点 实战演示Maven依赖版本号选择Spring及MQ主要配置基础信道绑定信道消息发送集成兼容多mq演示Rabbitmq演示Kafka演示 写在最后 前言 前面的博文我们介绍并实战演示了Spring Cloud Stream整合…

Java 使用 VisualVM 排查内存泄露

文章目录 1. 问题发生2. 排查过程2.1 初步排查2.2 Visual VM 内存分析2.3 代码分析 1. 问题发生 线上突发告警&#xff0c;笔者负责的一个服务老年代内存使用率到达 75% 阈值&#xff0c;于是立即登录监控系统查看数据。拉长时间周期&#xff0c;查看最近 7 天的 GC 和老年代内…

Transformer【ViT】

参考 导师&#xff01;博主的复现太细了。做个记录。 层神经网络学习小记录67——Pytorch版 Vision Transformer&#xff08;VIT&#xff09;模型的复现详解 计算机视觉中的transformer模型创新思路总结_Tom Hardy的博客-CSDN博 Vision Transformer详解 ViT 前处理 网络结…

2核4G轻量应用服务器性能测评(腾讯云PK阿里云)

阿里云轻量应用服务器2核4G4M带宽297.98元12个月&#xff0c;腾讯云轻量2核4G5M服务器168元一年&#xff0c;628元3年&#xff0c;2核4G轻量应用服务器阿里云和腾讯云怎么选择&#xff1f;哪个性能比较好&#xff1f;阿腾云分享轻量应用服务器2核4G配置阿里云和腾讯云CPU、带宽…

三种编码方式(费诺曼编码,霍夫曼编码,哈夫曼树编码)的简单解释和介绍

一. 费诺曼(Fano)编码是一种前缀编码&#xff0c;其基本原理是将出现频率较高的符号用短的编码表示&#xff0c;而出现频率较低的符号则用长的编码表示。通过这种方式进行编码&#xff0c;可以达到更好的压缩效果。 费诺曼编码的具体过程如下&#xff1a; 将要编码的符号按照…

书籍《银河帝国11:曙光中的机器人》观后感

这本书其实看完有段时间了&#xff0c;《银河帝国11:曙光中的机器人》是阿西莫夫写的《基地》系列第11本书&#xff0c;整个系列不是完全连贯的&#xff0c;本书是《银河帝国10》的后续。 先让我们来回忆一下前奏和背景吧&#xff0c;未来随着人类科技发展&#xff0c;遨游太空…

d2l学习——第一章Introduction

x.1 key components in ML 就和统计学习方法书中说的一样&#xff0c;机器学习也可以分为几个核心要义&#xff0c;Data, Models, Objective Functions, Optimization Algorithms&#xff0c; 其中&#xff1a; Data: 用来学习的数据Model: 如何转换/translate数据的模型Obje…

Vivado_除法器 IP核 使用详解

本文介绍使用Vivado中除法器Divider Generator&#xff08;5.1&#xff09;的使用方法。 参考资料&#xff1a;pg151 文章目录 Divider Generator仿真测试 Divider Generator Channel Settings选项卡 #Common Options&#xff1a; Algorithm Type: 一共有三种类型&#xff0c;…