使用 C++ 编写的 Qt 文本编辑器的 UTF-16LE 编码问题

UTF-16LE Encoding woes with Qt text editor written in C++

所以我已经开始创建一个 QT 文本编辑器。我从这个 http://doc.qt.io/archives/qt-5.7/gettingstartedqt.html 开始,并添加了它。到目前为止,我已经添加了一个适当的 save/save as 函数(link 中的版本实际上只有一个 save as 函数)、一个 "find" 函数和一个 "open new window" 函数。很快,我会添加一个查找和替换功能。

我这样做主要是为了学习经验,但我最终也会添加一些功能,这些功能将专门帮助我在工作中创建 PLC 配置文件。这些配置文件可能采用许多不同的编码,但其中大多数似乎采用 UTF-16LE(无论如何根据 Emacs。)我的文本编辑器最初读取 UTF-16LE 没有问题,但以纯文本形式编写,我需要改变那个。

以下是这些 UTF16-LE 文件之一的编码系统的 Emacs 描述片段。

U -- utf-16le-with-signature-dos (alias: utf-16-le-dos)
UTF-16 (little endian, with signature (BOM)).
Type: utf-16
EOL type: CRLF
This coding system encodes the following charsets:
  unicode

这里是我用来在 QT 文本编辑器中对文本进行编码的代码示例。

首先... 这与我之前给出的link类似。这里唯一的区别是 "saveFile" 是我创建的一个全局变量,用于执行简单的 "Save" 函数而不是 "Save As" 函数。这会将文本保存为纯文本并且非常有效。

void findreplace::on_actionSave_triggered()
{
    if (!saveFile.isEmpty())
    {
        QFile file(saveFile);
        if (!file.open(QIODevice::WriteOnly))
        {
            // error message

        }
        else
        {
            QTextStream stream(&file);
            stream << ui->textEdit->toPlainText();
            stream.flush();
            file.close();

        }
    }


}

下面是我的新版本,它试图将代码保存在 "UTF-16LE." 中,我的文本编辑器可以在用它保存后很好地阅读文本,但 Emacs 根本不会阅读它。这对我来说意味着读取它的程序可能无法读取配置文件。有些东西变了,不确定是什么。

void findreplace::on_actionSave_triggered()
{
    if (!saveFile.isEmpty())
    {
        QFile file(saveFile);
        if (!file.open(QIODevice::WriteOnly))
        {
            // error message

        }
        else
        {
            QTextStream stream(&file);
            stream << ui->textEdit->toPlainText();
            stream.setCodec("UTF-16LE");
            QString stream3 = stream.readAll();
            //QString stream2 = stream3.setUnicode();
            //QTextCodec *codec = QTextCodec::codecForName("UTF-16LE");
            //QByteArray stream2 = codec->fromUnicode(stream3);
            //file.write(stream3);
            stream.flush();
            file.close();

        }
    }


}

被注释掉的部分我也试过了,但他们最终把文件写成亚洲(中文或日文)字符。就像我说的,我的文本编辑器(和 Wine 中的记事本)可以很好地读取文件,但是 Emacs 现在在保存后将编码描述如下。

= -- no-conversion (alias: binary)

Do no conversion.

When you visit a file with this coding, the file is read into a
unibyte buffer as is, thus each byte of a file is treated as a
character.
Type: raw-text (text with random binary characters)
EOL type: LF

这表明文件中有些地方不对。最终,这个文本编辑器将用于一次创建多个文本文件并通过用户输入修改它们的内容。如果我能把这个编码正确,那就太好了。

感谢那些对我的 post 发表评论的好心人,我能够回答我自己的问题。这段代码解决了我的问题。

void findreplace::on_actionSave_triggered()
{
    if (!saveFile.isEmpty())
    {
        QFile file(saveFile);
        if (!file.open(QIODevice::WriteOnly))
        {
            // error message

        }
        else
        {
            QTextStream stream(&file);
            stream.setCodec("UTF-16LE");
            stream.setGenerateByteOrderMark(true);
            stream << ui->textEdit->toPlainText();
            stream.flush();
            file.close();

        }
    }


}

我设置了流的编解码器,然后将生成 BOM 设置为 "True." 我想我还有更多关于编码的知识要学习。我认为字节顺序标记必须设置为特定值,或者 something.I 不知道我只需将此值设置为 "True" 并且它会自行处理。 Emacs 现在可以读取通过使用此代码保存文档而生成的文件,并且来自 Emacs 的编码文档是相同的。我最终会添加选项,让用户在保存时选择他们需要的编码。很高兴我能在这里学到一些东西。