Qt:从固定字节数到整数

Qt: from a fixed number of bytes to an integer

我使用 Qt5.4 构建函数 generateRandomIDOver2Bytes。它生成一个随机数,并将其放入一个恰好占用两个字节的变量中。

QByteArray generateRandomIDOver2Bytes() {
    QString randomValue = QString::number(qrand() % 65535);
    QByteArray x;
    x.setRawData(randomValue.toLocal8Bit().constData(), 2);
    return x;
}

我的问题是还原如此生成的值,以便再次获得一个整数。 以下最小示例实际上不起作用:

QByteArray tmp = generateRandomIDOver2Bytes(); //for example, the value 27458 
int value = tmp.toUInt(); 
qDebug() << value; //it prints always 9

有什么想法吗?

给定随机值 27458,当您这样做时:

x.setRawData(randomValue.toLocal8Bit().constData(), 2);

你正在用这个字符串的前两个字节填充数组:“27458”。

这里:

int value = tmp.toUInt();

字节数组被隐式转换为字符串 ("27"),后者又被转换为数值(无符号整数)。

让我们尝试一些不同的东西,也许适合您的需要。

首先,将值存储在一个数值变量中,可能具有所需的大小(16 位,2 字节):

ushort randomValue = qrand() % 65535;

然后 return 一个字节数组,使用指向 ushort 的指针构建,转换为 char *(不要使用 setRawData,因为它不t 复制 你传入的字节,以及解释 here):

return QByteArray(reinterpret_cast<char *>(&randomValue), 2);

找回值:

QByteArray tmp = generateRandomIDOver2Bytes(); //for example, the value 27458

ushort value;
memcpy(&value, tmp.data(), 2);

请注意:类型在这里很重要。你在字节数组中写了一个 uint,你必须从中读出一个 uint

所有这些都可以概括为 class,例如:

template <typename T>
class Value
{
    QByteArray bytes;
public:
    Value(T t) : bytes(reinterpret_cast<char*>(&t), sizeof(T)) {}
    T read() const
    {
        T t;
        memcpy(&t, bytes.data(), sizeof(T));
        return t;
    }
};

所以你可以有一个像这样的通用函数:

template<typename T>
Value<T> generateRandomIDOverNBytes()
{
    T value = qrand() % 65535;
    qDebug() << value;
    return Value<T>(value);
}

并安全地使用您喜欢的类型来存储随机值:

Value<ushort> value16 = generateRandomIDOverNBytes<ushort>();
qDebug() << value16.read();

Value<int> value32 = generateRandomIDOverNBytes<int>();
qDebug() << value32.read();

Value<long long> value64 = generateRandomIDOverNBytes<long long>();
qDebug() << value64.read();

一个16位整数可以通过位操作拆分成一个个字节。

这样可以存成QByteArray.

来自 Qt 文档。共 QByteArray

QByteArray can be used to store both raw bytes (including '[=15=]'s) and traditional 8-bit '[=15=]'-terminated strings.

为了恢复,也可以使用位操作。

QByteArray 的内容不一定会生成可打印字符,但在这种情况下可能不需要(或不应)需要。

testQByteArrayWithUShort.cc:

#include <QtCore>

int main()
{
  quint16 r = 65534;//qrand() % 65535;
  qDebug() << "r:" << r;
  // storing r in QByteArray (little endian)
  QByteArray qBytes(2, 0); // reserve space for two bytes explicitly
  qBytes[0] = (uchar)r;
  qBytes[1] = (uchar)(r >> 8);
  qDebug() << "qBytes:" << qBytes;
  // recovering r
  quint16 rr = qBytes[0] | qBytes[1] << 8;
  qDebug() << "rr:" << rr;
}

输出:

r: 65534
qBytes: "\xFE\xFF"
rr: 65534