c++ - 为什么我在关于文件编码格式的 qt 代码中得到乱码结果?

标签 c++ qt locale

最近想学习qt如何对文件进行编解码。我测试了一些例子,但有些让我感到困惑。

这是我的代码:

#include <QApplication>
#include <QFile>
#include <QTextStream>

#define TEST(testFile) void test##testFile()

TEST(ANSI)
{
    QFile inFile(":/test/test-ANSI.txt");
    if (!inFile.open(QIODevice::ReadOnly | QIODevice::Text))
        return;

    QFile outFile("../test-ANSI-bak.txt");
    if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
        return;

    QTextStream in(&inFile);
    QTextStream out(&outFile);
    out.setCodec("UTF-8");

    // 这样写入会去掉换行符号
    while (!in.atEnd()) {
        QString line = in.readLine();
        out << line;
    }
}

TEST(GB2312)
{
    QFile inFile(":/test/test-GB2312.txt");
    if (!inFile.open(QIODevice::ReadOnly | QIODevice::Text))
        return;

    QFile outFile("../test-GB2312-bak.txt");
    if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
        return;

    QTextStream in(&inFile);
    QTextStream out(&outFile);
    out.setCodec("UTF-8");

    while (!in.atEnd()) {
        QString line = in.readLine();
        out << line;
    }
}

TEST(utf8BOM)
{
    QFile inFile(":/test/test-utf8-BOM.txt");
    if (!inFile.open(QIODevice::ReadOnly | QIODevice::Text))
        return;

    QFile outFile("../test-utf8-BOM-bak.txt");
    if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
        return;

    QTextStream in(&inFile);
    QTextStream out(&outFile);
    out.setCodec("UTF-8");

    while (!in.atEnd()) {
        QString line = in.readLine();
        out << line;
    }
}

TEST(utf8)
{
    QFile inFile(":/test/test-utf8.txt");
    if (!inFile.open(QIODevice::ReadOnly | QIODevice::Text))
        return;

    QFile outFile("../test-utf8-bak.txt");
    if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
        return;

    QTextStream in(&inFile);
    QTextStream out(&outFile);
    out.setCodec("UTF-8");

    while (!in.atEnd()) {
        QString line = in.readLine();
        out << line;
    }
}

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

    testANSI();
    testGB2312();
    testutf8BOM();
    testutf8();

    return app.exec();
}

我输入的文字内容如下:

----
I love you!
我爱你!
。。。
1234
1234

对于ANSI、GB2312、utf8-BOM,我得到了输出文件 例如:test-ANSI-bak.txt

----I love you!我爱你!。。。12341234

对于utf8,我得到了输出文件 例如:test-utf8-bak.txt

----I love you!鎴戠埍浣狅紒銆傘€傘€12341234

为什么test-utf8-bak.txt会显示乱码?我很困惑!

最佳答案

QTextStream 正在根据输入文件内容猜测编解码器,对于非 BOM utf-8 文件,它猜测不正确。

如果您知道输入文件的格式,您应该调用 in.setCodec(),如果您不知道格式,您将不得不继续依赖 Qt 的猜测或编写您自己的编码探测器。

看起来 QTextStream 只查找 BOM,不做任何其他 Unicode 检测,来自 http://doc.qt.io/qt-5/qtextstream.html :

Automatic Unicode detection is also supported. When this feature is enabled (the default behavior), QTextStream will detect the UTF-16 or the UTF-32 BOM (Byte Order Mark) and switch to the appropriate UTF codec when reading

关于c++ - 为什么我在关于文件编码格式的 qt 代码中得到乱码结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49644540/

相关文章:

java - 为不同的语言环境定制 java.text 格式化程序

java - 检查提供的语言环境是否存在

linux - 每当我在 ubuntu 中打开手册页时,我都会看到此警告

c++ - 从 const 引用参数存储成员变量

c++ - sleep_until 不适用于 MSVC 中的 steady_clock

c++ - 如何在 x64 平台上使用 HTMLHelpCtrl.ocx ActiveX 控件

c++ - 使用内置 MySQL 库静态构建 Qt

模块中的 C++ "Using"

c++ - 迭代合并排序,与冒泡排序速度相同

c++ - QMetaObject::indexOfMethod 返回的索引到底是什么?