2

在此处输入图像描述我正在开发一个 QT 项目(Qt Creator 5.2.1),该项目具有接收 UDP 数据报中的设备 IP 地址的功能。我需要将其转换为 QString 才能正确输出到屏幕。数据报作为整数数据存储在称为“缓冲区”的 QByteArray 中 - 因此 10.1.10.60 的 IP 地址在数据报中显示为 0A010A3C。我正在尝试将 IP 地址存储在 QString“nburn_data”中。目前我有这个代码来处理它:

nburn_data.append(QString::fromUtf8(buffer.left(2).toHex().toUpper(), 
    buffer.left(2).size()));

当输出显示在屏幕上(GUI)我没有得到“10.1.10.60”,我得到“0A.01.0A.3C”

我尝试了几种不同的方法来正确转换,但似乎没有任何效果。有什么建议么?

编辑:@Laszlo Papp-我附上了一张图片以及建议代码的输出(突出显示)。相关代码和输出

4

2 回答 2

2

如果我正确阅读了您的问题,您只需要以下内容:

nburn_data.append(QStringLiteral("%1.%2.%3.%4")
    .arg((unsigned)buffer[0]).arg((unsigned)buffer[1])
    .arg((unsigned)buffer[2]).arg((unsigned)buffer[3]));

对于 Qt4,替换QStringLiteralQString. 对于某种“C++ 纯度”,将 C 样式转换替换为static_cast(尽管我认为使用 C 样式转换以防这种情况更好)。


如果您想使用 Qt 提供的功能来解析二进制数据,尤其是 IPv4 地址,那么这里有一些东西供您研究。

#include <QByteArray>
#include <QDataStream>
#include <QHostAddress> // note: .pro file needs QT += network
#include <QString>
#include <QDebug>

int main(void)
{
    // dummy data, big endian IPv4 address 10.1.10.60 at byte offset 4
    QByteArray buffer = QByteArray::fromHex("FFFFFFFF0A010A3CFFFFFFFF");
    int addr_offset = 4;

    // output string
    QString nburn_data("IP Address: ");

    Q_ASSERT(buffer.size() >= addr_offset + 4); // assert that buffer is big enough

    // initialize QDataStream for parsing buffer data
    QDataStream parser(&buffer, QIODevice::ReadOnly);
    //parser.setByteOrder(QDataStream::BigEndian); // big endian is default
    parser.skipRawData(addr_offset);               // only needed if not at offset 0

    // parse the address
    quint32 addr = 0x00BADBAD;                    // 0.x.x.x is invalid IPv4 addr
    parser >> addr;                               // actual parsing happens here
    Q_ASSERT(parser.status() == QDataStream::Ok); // assert that buffer was big enough

    // use temporary QHostAddress object to convert address to string
    nburn_data.append(QHostAddress(addr).toString());

    qDebug() << nburn_data;

    return 0;
}

输出:

"IP Address: 10.1.10.60"

笔记:

  • QDataStream对于更复杂和可变长度的数据有自己的序列化格式,因此在将其用作通用二进制数据解析器时必须小心
  • 由于除了这里没有其他错误检查Q_ASSERT,它不会在发布构建中做任何事情,所以最好初始化addr而不是让它未初始化,以防QDataStream出现错误并且不更改其值。
  • QDataStream无法从错误中恢复,因此不应该直接在网络套接字上使用,应该QByteArray在解析之前放入完整的数据。
  • 虽然这段代码没有QCoreApplication实例,而且这里使用的所有类都不需要它,但许多 Qt 类确实需要它。
于 2014-04-29T04:11:02.593 回答
0

我不明白你试图用你的代码做什么,因为它似乎是乱序的,但下面的代码对我有用:

主文件

#include <QString>
#include <QByteArray>
#include <QDebug>

int main()
{
    QByteArray buffer = "0A010A3C";
    QString nburn_data;
    bool ok;
    for (int i = 0; i < 8; i+=2) {
        if (i)
            nburn_data.append('.');
        nburn_data.append(QByteArray::number(buffer.mid(i, 2).toInt(&ok, 16)));
        // when using int buffer, then replace the above line with this:
        // nburn_data.append(buffer.mid(i, 2));
    }
    qDebug() << nburn_data;
    return 0;
}

主程序

TEMPLATE = app
TARGET = main
QT = core
SOURCES += main.cpp

构建并运行

qmake && make && ./main

输出

"10.1.10.60"

编辑:由于您似乎在更新问题时更改了输入,因此您需要对我之前回答您原始问题的代码进行此更新:

tempbuffer = tempbuffer.toHex(); // before the loop in your code

或者你可以在我的循环中删除不必要的数字转换,所以用这个替换内行:

nburn_data.append(buffer.mid(i, 2));
于 2014-04-28T20:04:48.967 回答