【问题标题】:Detect text file encoding检测文本文件编码
【发布时间】:2013-08-14 08:36:30
【问题描述】:

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

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,而不要求用户告诉我编码?

【问题讨论】:

  • 恐怕不是,真的。纯文本文件的诅咒。一个快速的谷歌支持这一点:qt-project.org/forums/viewthread/12619
  • 尝试将文本解码为 UTF-8。如果失败,则不是 UTF-8。
  • 我怎么知道它失败了?
  • @Mattsjo 是的,我在发布我的问题之前阅读了该内容。第二部分怎么样 - 只是区分 UTF-8 和 Windows-1252?那可能吗?顺便说一句,我知道 Notepad++ 可以做到这一点,但可能他们为此编写了很多代码。
  • 什么意思?你知道什么是UTF-8吗?您可以判断一个字节序列是否是有效的 UTF-8 序列。

标签: c++ qt character-encoding


【解决方案1】:

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

但是,如果文本不是有效的 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

【讨论】:

    【解决方案2】:

    这个技巧对我有用,至少到目前为止。此方法不需要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);
        }
    

    【讨论】:

      猜你喜欢
      • 2021-12-30
      • 1970-01-01
      • 2010-09-10
      • 2011-05-30
      • 2012-12-23
      • 1970-01-01
      • 2018-07-30
      相关资源
      最近更新 更多