Qt C++ QString 转换为 QByteArray

38

我创建了一个加密/解密程序,加密时,我将加密后的 QByteArray 存储在文本文件中。

但是,在尝试解密时,我需要检索它并将其放入解密方法中,问题是我需要一种将其转换为 QByteArray 的方式而不改变格式,否则它将无法正确解密。我的意思是,如果文件给我一个加密值1234,我通过 1234.toLatin1() 进行转换,它会改变值,解密就无法正常工作。有什么建议吗?

我的代码:

QFile file(filename);
    QString encrypted;
    QString content;

    if (file.open(QIODevice::ReadOnly)) {
        QTextStream stream( &file );
        content = stream.readAll();
    }

    encrypted = content.replace("\n", "");

    qDebug() << encrypted; // Returns correct encrypted value

    QByteArray a;
    a += encrypted;

    qDebug() << "2 " + a; // Returns different value than previous qDebug()

    QByteArray decrypted = crypto.Decrypt(a, key);
    return decrypted;

你是如何将 QByteArray 写入文本文件的?是使用 QTextStream 还是直接使用 QFile::write? - Daniel
@Daniel QTextStream - James
5个回答

46

我想你应该使用:

QString::fromUtf8(const QByteArray &str)

或者:

QString::QString(const QByteArray &ba)

将 QByteArray 转换为 QString,然后使用 QTextStream 将其写入文件。之后,通过 QTextStream 读取文件,使用:
QString::toUtf8()

将QString转换为QByteArray。

QString::QString(const QByteArray &ba)

构造一个用字节数组ba初始化的字符串。给定的字节数组使用fromUtf8()函数转换为Unicode编码。


P.S: 也许使用QFile::write和QFile::read是更好的方法。


我宁愿直接使用QString::fromUtf8,而不是隐式的QString<->QByteArray转换,这样可以使纯数据和Unicode之间的转换变得明确,并声明数据的假定编码。 - Frank Osterfeld
4
标题所示与此相反,对于查找类似问题的人来说... - Christopher Pisz

10

尝试使用toUtf8()..它对我来说效果很好


1
toUtf8() 可能是更好的选择,因为它可以处理 QString 能够处理的所有字符。 - Soren Stoutner

0

或者直接使用 b64 = data.toUtf8().toBase64();

首先使用 toUtf8() 将其转换为 QByteArray,然后立即将其转换为 toBase64()


0
如果我理解正确,文件中的文本存储在 QString content 中。我认为你可以创建一个新的 QByteArray。因为 QByteArray 的构造函数不允许输入 QString,所以我可能需要将 QString 追加到空的 QByteArray 中。
//After if:  
QByteArray tempContent();
tempContent.append(content);
QByteArray decrypted = crypto.Decrypt(tempContent, key);

我在Qt库方面没有太多经验,但希望这可以帮到你。


这确实成功转换了,但在测试后返回了?\x01?YJ?l?p3&?\x11\x1Bv/?X??c?U?~{?a??,而应该是?\u0001?YJ?l?p3&?\u0011\u001Bv/?X??c?U?~{?a??。为什么值会改变?因为我在创建QByteArray之前使用了qDebug()content,所以这是正确的值。 - James
我已经编辑了我的帖子,并添加了整个函数,如果有帮助的话。 - James
不知道为什么这个被踩了,它完全没问题。 - Zimano
这将隐式执行ASCII或Latin1编码转换,因此Unicode无法使用它。这就是为什么Qt允许禁用此构造函数的原因。 - wheredidthatnamecomefrom

0

有一种简单的方法:

   QByteArray ba;
   QString qs = "String";
   ba += qs;

更困难的方法:

QByteArray ba;
QDataStream in(&ba, QIODevice::WriteOnly);
in << QString("String");

对于想要使用 QBuffer 的人来说,是一种极端的方式:

#include <QDebug>
#include <QBuffer>
#include <QDataStream>
#include <QIODevice>
#include <QByteArray>
#include <QString>
#include <qcoreapplication.h>

int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   QByteArray byteArray;
   QBuffer buffer(&byteArray);
   buffer.open(QIODevice::ReadWrite);
   QDataStream in( &buffer );
   in << QString("String");
   buffer.close();

   for (int i = 0; i < byteArray.length(); ++i) {
      printf("%c - %x\n", byteArray.at(i), byteArray.at(i));
   }

   printf("\n");
   

return a.exec();
}

运行最后一段代码的人可以问我这个 null byte 来自哪里?

QDataStreamQString 序列化为小端格式。读取 4 个字节创建 32 位长度值,然后是 UTF-16 编码的字符串本身。UTF-16 编码的字符串长度为 12 字节,因此 QByteArray 中的前三个字节将为零。

在使用 qDebug() 读取 QByteArray 时经常会出现问题,但记录正常。 如果您的项目中有 QT_NO_CAST_FROM_BYTEARRAY,请别忘了在您的 .pro 文件中移除它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接