2

ここに画像の説明を入力UDPデータグラムでデバイスのIPアドレスを受け取る機能を備えたQTプロジェクト(Qt Creator 5.2.1)に取り組んでいます。画面に正しく出力するには、QStringに変換する必要があります。データグラムは「buffer」と呼ばれる QByteArray に整数データとして格納されます。そのため、10.1.10.60 の IP アドレスはデータグラムでは 0A010A3C として表示されます。QString "nburn_data" に IP アドレスを保存しようとしています。現在、私はそれを処理するためのこのコードを持っています:

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 の場合は、 に置き換えQStringLiteralますQString。特定の種類の「C++ 純度」については、C スタイルのキャストを次のように置き換えstatic_castます (ただし、このような場合は C スタイルのキャストを使用する方がよいと思います)。


バイナリ データ、特に IPv4 アドレスを解析するために Qt が提供する機能を使用したい場合は、ここで何かを勉強してください。

#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

コードが順不同のように見えるため、コードで何をしようとしているのかわかりませんが、次のコードは私にとってはうまくいきます:

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));
于 2014-04-28T20:04:48.967 に答える