Question

enter image description hereI'm working on a QT project (Qt Creator 5.2.1) with a function that receives a receives a device's IP address in a UDP datagram. I need to convert it to a QString to correctly output to the screen. The datagram is stored in a QByteArray called "buffer" as integer data - so the IP address of 10.1.10.60 shows up in the datagram as 0A010A3C. I'm trying to store the IP address in a QString "nburn_data". Currently I have this code for handling it:

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

When the output is put to the screen (GUI) I don't get "10.1.10.60", I get "0A.01.0A.3C"

I've tried a few different methods to convert correctly, but nothing seems to be working. Any suggestions?

Edit: @Laszlo Papp- I've attached an image along with the output (highlighted) from suggested code. Relevant Code and Output

Was it helpful?

Solution 2

I do not understand what you try to do with your code as it seems to be out of order, but the following code works for me:

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

Build and Run

qmake && make && ./main

Output

"10.1.10.60"

Edit: since you seem to have changed your input when updating the question, you will need to this update to my previous code answering your original question:

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

or you could just remove the needless number conversion in my loop, so replacing the inner line with this:

nburn_data.append(buffer.mid(i, 2));

OTHER TIPS

If I read your question correctly, you want simply this:

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

For Qt4, replace QStringLiteral with QString. For certain kind of "C++ purity", replace C-style cast with static_cast (though I'd argue using C-style cast in case like this is better).


If you want to use features offered by Qt for parsing binary data, and IPv4 addresses in particular, then here's something for you study.

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

Output:

"IP Address: 10.1.10.60"

Notes:

  • QDataStream has it's own serialization format for more complex and variable length data, so care must be taken when using it as general purpose binary data parser
  • Since there is no other error checking than Q_ASSERT here, which will not do anything in release build, it's good to initialize addr instead of leaving it uninitialized, in case QDataStream has error and does not change its value.
  • QDataStream can't recover from errors, so it should not be used directly on network socket, complete data should be put to QByteArray before parsing.
  • while this code does not have a QCoreApplication instance, and none of the classes used here need it, many Qt classes do require it.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top