Reputation: 493
I'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.
Upvotes: 2
Views: 1802
Reputation: 62898
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 parserQ_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.QCoreApplication
instance, and none of the classes used here need it, many Qt classes do require it.Upvotes: 2
Reputation: 53215
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:
#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"
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));
Upvotes: 0