5

在我的程序中,我加载了用户提供的纯文本文件:

QFile file(fileName);
file.open(QIODevice::ReadOnly);
QTextStream stream(&file);
const QString &text = stream.readAll();

当文件是 UTF-8 编码时,这可以正常工作,但是一些用户尝试导入 Windows-1252 编码的文件,并且如果他们有带有特殊字符的单词(例如“boutonnière”中的“è”),这些将不正确地显示。

有没有办法检测编码,或者至少区分 UTF-8(可能没有 BOM)和 Windows-1252,而不要求用户告诉我编码?

4

2 回答 2

4

这个技巧对我有用,至少到目前为止。此方法不需要 BOM 即可工作:

    QTextCodec::ConverterState state;
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    const QByteArray data(readSource());
    const QString text = codec->toUnicode(data.constData(), data.size(), &state);
    if (state.invalidChars > 0)
    {
        // Not a UTF-8 text - using system default locale
        QTextCodec * codec = QTextCodec::codecForLocale();
        if (!codec)
           return;

        ui->textBrowser->setPlainText(codec->toUnicode(readSource()));
    }
    else
    {
        ui->textBrowser->setPlainText(text);
    }
于 2014-10-16T18:28:46.703 回答
4

事实证明,对于一般情况,自动检测编码是不可能的。

但是,如果文本不是有效的 UTF-8/UTF-16/UTF-32 文本,有一种解决方法至少可以回退到系统语言环境。它使用QTextCodec::codecForUtfText(), 尝试使用 UTF-8、UTF-16 和 UTF-32 解码字节数组,如果失败则返回提供的默认编解码器。

执行此操作的代码:

QTextCodec *codec = QTextCodec::codecForUtfText(byteArray, QTextCodec::codecForName("System"));
const QString &text = codec->toUnicode(byteArray);

更新

但是,上面的代码不会检测没有 BOM 的 UTF-8,因为 codecForUtfText() 依赖于 BOM 标记。要检测没有 BOM 的 UTF-8,请参阅https://stackoverflow.com/a/18228382/492336

于 2013-08-15T13:20:44.737 回答