系列文章目录

前言

使用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();
}

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

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

使用了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%准确,特别是对于一些特殊或混合编码的文件,可能会有误判。因此,最好还是能够事先知道文件的准确编码格式,或者提前约定好文件的编码方式。

06-08 17:32