【问题标题】:Converting Character data to QString in Qt Creator在 Qt Creator 中将字符数据转换为 QString
【发布时间】:2014-06-14 10:34:09
【问题描述】:

我正在开发一个 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- 我附上了一张图片以及建议代码的输出(突出显示)。

【问题讨论】:

  • 请不要发截图,而是复制粘贴相关文字。
  • 对不起,我不知道截图是违反论坛规则的。下次我会记住的。

标签: c++ qt qstring qtcore qbytearray


【解决方案1】:

如果我没看错你的问题,你只需要这个:

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,将 QStringLiteral 替换为 QString。对于某种“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不能从错误中恢复,所以不应该直接在网络socket上使用,完整的数据应该在解析前放到QByteArray
  • 虽然这段代码没有QCoreApplication 实例,而且这里使用的所有类都不需要它,但许多Qt 类确实需要它。

【讨论】:

  • 谢谢。这产生了我正在寻找的输出。我的代码现在可以正确读取。我从没想过要使用 QStringLiteral 宏——我没想到。非常感谢!
  • @LaszloPapp,如果我的问题没有得到很好的定义,我深表歉意,我是一名硬件工程师,最近刚进入软件领域,没有经验,只能弄清楚..可以这么说。因此,如果不清楚,请原谅。正如我在下面回复的那样,我有海德提到的 int 形式的数据,即 IPv4 地址。我需要将其转换为文本以在屏幕上显示。无论我做什么,我都能够得到“0A.01.0A.3C”的输出,而不是前面提到的“10.1.10.60”。我在原始帖子中发布了您最近使用的方法的屏幕截图。
  • @hyde - 我不担心这个应用程序的优化。不涉及关键时间,只需单击一个按钮,它就会向设备发送一个 16 字节的数据包,然后接收一个返回。而已。数据包之间的时间为 150 毫秒。
  • gui 上有一个“主机端口”框,用户输入端口号并单击“查找设备”,它将 5 字节的 UDP 数据包广播到端口 20034 上的任何设备。 Netburner 单元响应一个 148 字节的数据包。在该数据包中是设备的 IP 地址。如果我正确理解您的问题,那么来自 netburner 单元的数据包就是输入。我正在尝试从数据包中提取 IP 地址,并将其从 int 形式转换为文本以显示在屏幕上。就是这样。
  • 大杂烩-0A010A3C
【解决方案2】:

我不明白你试图用你的代码做什么,因为它似乎有问题,但以下代码对我有用:

main.cpp

#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;
}

main.pro

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));

【讨论】:

  • 谢谢@Laszlo,但也许我做错了什么,因为这对我不起作用......我使用“start”而不是nburn_data,因为后者拥有比IP更多的信息点在代码中。代码:`bool ok; QByteArray tempbuff = buffer.left(4).data(); qDebug()
  • 我需要一个更长的评论框......由于某种原因,我所有的试验结果都是一样的。我可以查看要转换的数据,只是由于某种原因无法转换。
  • 是的,我确实尝试过代码。我刚刚附上了一个屏幕截图 - 代码在屏幕上,该代码部分的 qDebug() 输出在底部以蓝色突出显示。
  • hyde 已经提出了解决方案,正如他所说,我从没想过使用 QStringLiteral 宏...但是非常感谢您以这种方式提供的帮助。您现在已经回答了我的一些帖子,作为一个新手,非常感谢。老实说,我仍然不确定为什么尝试的其他方法不起作用。所有迹象都表明他们应该这样做。再次非常感谢您的帮助!
  • @JediEngineer:这是因为您的临时缓冲区实际上并不包含您在问题中所写的十六进制数!尝试通过转换自身将循环之前的十六进制内容转换为 tempbuffer,然后一切正常。 hyde 的解决方案可能有效,但它与 Qt 的设计方式相去甚远,恕我直言,应该使用它。 :) 在循环之前尝试tempbuffer = tempbuffer.toHex();,然后它将起作用。我个人建议在 C++ 项目中使用这种风格而不是低级 C'ish 编程风格,尤其是当你有方便的 Qt 方法来提高可读性等时。:)
猜你喜欢
  • 1970-01-01
  • 2011-12-23
  • 2014-04-18
  • 1970-01-01
  • 2013-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-18
相关资源
最近更新 更多