29

What is the correct way to convert losslessly between std::string and QByteArray... mostly for the purpose of handling binary data?

I'm using:

QByteArray qba = QString::fromStdString(stdString).toAscii();

and

QString(qba).toStdString();

but I wanted to check whether this is actually correct.

leemes
  • 44,967
  • 21
  • 135
  • 183
Jake Petroules
  • 23,472
  • 35
  • 144
  • 225

3 Answers3

45

For binary data your solution is problematic since non-ASCII characters would be converted to '?' by QString::toAscii(). There is also the unnecessary overhead of UTF-16 conversion for the internal representation of QString. As you might have guessed, QString should only be used if the data is textual, not binary.

Both QByteArray and std::string have constructors for raw data (C-string + length) and also a conversion to C-string + length. So you can use them for conversion:

// std::string => QByteArray
QByteArray byteArray(stdString.c_str(), stdString.length());

// QByteArray => std::string
std::string stdString(byteArray.constData(), byteArray.length());

They are both binary-safe, meaning that the string may contain '\0' characters and doesn't get truncated. The data also doesn't get touched (there is no UTF conversion), so this conversion is "lossless".

Make sure to use the constructors with the length as the second argument (for both QByteArray and std::string), as most other constructors will truncate the data before the first occurrence of a zero.

leemes
  • 44,967
  • 21
  • 135
  • 183
  • Thanks. Important to keep in mind that certain constructors of std::string won't necessarily take all the data and will truncate at the first null byte. – Jake Petroules May 26 '12 at 16:33
  • Yes, thanks for adding this information, I will add it to the answer. But the constructor with the length as its 2nd argument won't truncate. – leemes May 26 '12 at 20:20
20

As of Qt 5.4, QByteArray has built in support for std::string conversions via QByteArray::toStdString() and QByteArray::fromStdString().

These are implemented almost identically to leemes' answer.

inline std::string QByteArray::toStdString() const
{ return std::string(constData(), length()); }

inline QByteArray QByteArray::fromStdString(const std::string &s)
{ return QByteArray(s.data(), int(s.size())); }
Community
  • 1
  • 1
Parker Coates
  • 8,520
  • 3
  • 31
  • 37
-5

QByteArray datagram; datagram.append(ui->lineEdit_sendData->text());