How do I see the contents of Qt objects QByteArray during debugging? - c++

My program use some variables of type QByteArray to contain data (bytes). That bytes maybe are special characters like '\0', 1, ... So I cannot see all elements after special character when debugging. If I use std::vector, I can see all elements. I must use QByteArray but I cannot see all element of this variable when debugging. Help me, plz!
Thanks!
Example: QByteArray bytes(4, '\0');
Now, if debug, I just see "". But I want to see "'\0', '\0', '\0', '\0'" or something like like this.
I also have the same problem with QDateTime. But I resolved by this help: http://www.qtcentre.org/threads/32336-View-QDate-and-QDateTime-in-VisualStudio-debugger
This link may help but this not resolve my problem: http://qt-project.org/wiki/IDE-debug-helpers
Example:
QByteArray ba("Hello"); //debuging, see: ba = "Hello"
ba.append('\0');
ba.append("a message"); //we just see: ba = "Hello"

I contribute here a piece of code I had to write since I could not find any method doing something close to that: display a QByteArray as a meaningful QString in a way python would do it: ascii is kept as this, special char are displayed as hexadecimal code.
If someone knows a better way ! (here it's QT 4.6)
QString toDebug(const QByteArray & line) {
QString s;
uchar c;
for ( int i=0 ; i < line.size() ; i++ ){
c = line[i];
if ( c >= 0x20 and c <= 126 ) {
s.append(c);
} else {
s.append(QString("<%1>").arg(c, 2, 16, QChar('0')));
}
}
return s;
}
Such as:
QByteArray a;
a.append("et");
a.append('\0');
a.append("voilĂ ");
qDebug() << toDebug(QByteArray(a));
returns:
"et<00>voil<e0>"

For debugging, you can convert QBytearray to QString and see the output.
For example:
QByteArray bArray;
QString str = "";
str.append(bArray);
QDebug() << str ; // this will display the content in your console/application output window
hope this will resolve your issue.

Related

Displays unwanted character while converting from QDataStream to QChar

I have a code as below
QByteArray bla("abcde");
QDataStream ds(bla.right(bla.size()-1));
QChar c;
ds>>c;
qDebug()<<c; // It prints '?' instead of 'b'
It prints out b if I change the code as
qint8 c;
ds>>c;
qDebug()<<QChar(c); // It now prints 'b'.
It's ok for a single character suppose, I have a lot of characters then I need to make a loop and cast every single of them . Please suggest a good approach.
ds>>c; equals ds>>c.unicode();, which has type ushort &. While QByteArray contains chars.
The correct way to converting QBytaArray to a sequence of QChar would be:
QByteArray bla("abcde");
QTextCodec *codec = QTextCodec::codecForLocale();
const QString string = codec->toUnicode(bla);
foreach (const QChar &c, string) {
qDebug() << c;
}

QByteArray: how to search a character in it

Starting from a QByteArray, I'd like to search "\n" char inside my QByteArray and join all the characters from the beginning up to "\n" and save them in a QString; after that, I'd pass to the following bytes up to the next "\n" and save these into a new QString
QByteArray MyArray= (all data from my previous process);
quint16 ByteArrayCount = MyArray.count(); // number of bytes composing MyArray
quint16 mycounter;
QString myString;
while (mycounter < ByteArrayCount)
{
if(MyArray[mycounter] != "\n")
myString.append(MyArray[mycounter]);
mycounter++;
}
This to append all bytes preceeding a new line; my problem is how to evaluate MyArray[counter], since I'm not able to check every byte when the counter increases.
Solution?
You could save yourself the trouble and simply:
QString s(myArray);
QStringList resultStrings = s.split('\n');
This will give you a list of strings split for every new line character, which is what you sound like you want to do.
Also, not to belabor the point, but you don't initialize your counter, and you really should ;)
Here is simple example of using function hello
QString str = "ooops\nhello mama\n daddy cool";
QByteArray bta;
bta.append(str);
for(quint16 index = bta.indexOf('\n');
index != -1;
index = bta.indexOf('\n', index+1)) {
/**
* Do something with index
**/
}
But according to your question there is not so clear when you say that you "not able to check every byte". If you know diapasons of available mem, you can use raw data with:
const char * ptr = MyArray.constData();
and use custom validators:
while(ptr){
if(valid(ptr) && ptr == '\n') {
/**
* do something ...
**/
}
ptr++;
}
ow and also in C/C++:
"\n" != 'n'
because "\n" - is const C string(char[2]) containing \n and EOF('\0')
and '\n' - is just simple C char;

Convert char * to QString and remove zeros

In my app I read a string field from a file in local (not Unicode) charset.
The field is a 10 bytes, the remainder is filled with zeros if the string < 10 bytes.
char str ="STRING\0\0\0\0"; // that was read from file
QByteArray fieldArr(str,10); // fieldArr now is STRING\000\000\000\000
fieldArr = fieldArr.trimmed() // from some reason array still containts zeros
QTextCodec *textCodec = QTextCodec::codecForLocale();
QString field = textCodec->ToUnicode(fieldArr).trimmed(); // also not removes zeros
So my question - how can I remove trailing zeros from a string?
P.S. I see zeros in "Local and Expressions" window while debuging
I'm going to assume that str is supposed to be char const * instead of char.
Just don't go over QByteArray -- QTextCodec can handle a C string, and it ends with the first null byte:
QString field = textCodec->toUnicode(str).trimmed();
Addendum: Since the string might not be zero-terminated, adding storage for a null byte to the end seems to be impossible, and making a copy to prepare for making a copy seems wasteful, I suggest calculating the length ourselves and using the toUnicode overload that accepts a char pointer and a length.
std::find is good for this, since it returns the ending iterator of the given range if an element is not found in it. This makes special-case handling unnecessary:
QString field = textCodec->toUnicode(str, std::find(str, str + 10, '\0') - str).trimmed();
Does this work for you?
#include <QDebug>
#include <QByteArray>
int main()
{
char str[] = "STRING\0\0\0\0";
auto ba = QByteArray::fromRawData(str, 10);
qDebug() << ba.trimmed(); // does not work
qDebug() << ba.simplified(); // does not work
auto index = ba.indexOf('\0');
if (index != -1)
ba.truncate(index);
qDebug() << ba;
return 0;
}
Using fromRawData() saves an extra copy. Make sure that the str
stays around until you delete the ba.
indexOf() is safe even if you have filled the whole str since
QByteArray knows you only have 10 bytes you can safely access. It
won't touch 11th or later. No buffer overrun.
Once you removed extra \0, it's trivial to convert to a QString.
You can truncate the string after the first \0:
char * str = "STRING\0\0\0\0"; // Assuming that was read from file
QString field(str); // field == "STRING\0\0\0\0"
field.truncate(field.indexOf(QChar::Null)); // field == "STRING" (without '\0' at the end)
I would do it like this:
char* str = "STRING\0\0\0\0";
QByteArray fieldArr;
for(quint32 i = 0; i < 10; i++)
{
if(str[i] != '\0')
{
fieldArr.append(str[i]);
}
}
QString can be constructed from a char array pointer using fromLocal8Bit. The codec is chosen the same way you do manually in your code.
You need to set the length manually to 10 since you say you have no guarantee that an terminating null byte is present.
Then you can use remove() to get rid of all null bytes. Caution: STRI\0\0\0\0NG will also result in STRING but you said that this does not happen.
char *str = "STRING\0\0\0\0"; // that was read from file
QString field = QString::fromLocal8Bit(str, 10);
field.remove(QChar::Null);

Sending a big buffer through uart in Qt5

I'm a beginner in Qt. Now I want to use Qt5 to send a 9-byte command through uart.
Here is my command:
FFFFFF5550464DAA0E
I want to transfer my command to a Qstring object. When I write my code like this, it tells me the const is too big.
QString str=0xFFFFFF5550464DAA0E;
So I choose an array like this, but it still doesn't work.
char cmd[9]={0xFF,0xFF,0xFF,0x55,0x50,0x46,0x4D,0xAA,0x0E};
for(int i=0;i<9;i++)
{
QString str=cmd[i];
QByteArray outData=str.toLatin1();
int size=outData.size();
outData=myHelper::HexStrToByteArray(str);
size=outData.size();
myCom->write(outData);
}
I also try this which failes again
char cmd[9]={0xFF,0xFF,0xFF,0x55,0x50,0x46,0x4D,0xAA,0x0E};
QString str=cmd;
QByteArray outData=str.toLatin1();
int size=outData.size();
outData=myHelper::HexStrToByteArray(str);
size=outData.size();
myCom->write(outData);
So could anyone tell me how to do this ?
This line of code:
QString str=0xFFFFFF5550464DAA0E;
0xFFFFFF5550464DAA0E is not a string. You're trying to assign a very big constant (9 bytes) number to a string. Note that 0xFF is not a string but a character with ASCII code 0xFF. With your second attempt you're on the right way:
char cmd[9]={0xFF,0xFF,0xFF,0x55,0x50,0x46,0x4D,0xAA,0x0E};
Now you have two options; it depends on what you have to send, 9 bytes or a longer string with that commands represented as a hex string and encoded as ASCII. First case is easier, drop all your code:
QByteArray outData = QByteArray(cmd, sizeof(cmd));
myCom->write(outData);
With this code you won't send a string to your device but 9 bytes (0xFF...0x0E). If you have to send a string then you can do what paxdiablo suggested:
QByteArray outData = QByteArray("\xFF\xFF\xFF\x55\x50\x46\x4D\xAA\x0E", 9);
myCom->write(outData);
Or:
QByteArray outData = QString("0xFF0xFF0xFF0x550x500x460x4D0xAA0x0E")
.toLatin1();
myCom->write(outData);
Or in alternative you can do this:
char cmd[9]={0xFF,0xFF,0xFF,0x55,0x50,0x46,0x4D,0xAA,0x0E};
QByteArray outData = QByteArray(cmd, sizeof(cmd)).toHex();
myCom->write(outData);
Which one is right for you? Well you should clarify your context...
You don't need to mess about with strings and conversions. You can just make the QByteArray directly from the data itself, with a simple one-liner:
QbyteArray data("\xFF\xFF\xFF\x55\x50\x46\x4D\xAA\x0E", 9);
Following that, the statement:
myCom->write(data);
will then output the nine bytes as specified in the string.

QByteArray to QString

I'm having issues with QByteArray and QString.
I'm reading a file and stores its information in a QByteArray. The file is in unicode, so it contains something like: t\0 e\0 s\0 t\0 \0 \0
I'm trying to compare this value to my specified value, but it fails, because in the debugger I see it's not an unicode string.
The code will explain everything:
QByteArray Data; //contains unicode string "t\0 e\0 s\0 t\0 \0 \0"
QString myValue = "test"; //value to compare.
if(Data.contains(myValue))
//do some stuff.
else
//do other stuff.
In the debugger, it shows me that the variable Data has the value "t\0 e\0 s\0 t\0 \0 \0" and myValue has the value "test". How can I fix it?
You can use this QString constructor for conversion from QByteArray to QString:
QString(const QByteArray &ba)
QByteArray data;
QString DataAsString = QString(data);
You can use QTextCodec to convert the bytearray to a string:
QString DataAsString = QTextCodec::codecForMib(1015)->toUnicode(Data);
(1015 is UTF-16, 1014 UTF-16LE, 1013 UTF-16BE, 106 UTF-8)
From your example we can see that the string "test" is encoded as "t\0 e\0 s\0 t\0 \0 \0" in your encoding, i.e. every ascii character is followed by a \0-byte, or resp. every ascii character is encoded as 2 bytes. The only unicode encoding in which ascii letters are encoded in this way, are UTF-16 or UCS-2 (which is a restricted version of UTF-16), so in your case the 1015 mib is needed (assuming your local endianess is the same as the input endianess).
You can use:
QString::fromStdString(byteArray.toStdString())
you can use QString::fromAscii()
QByteArray data = entity->getData();
QString s_data = QString::fromAscii(data.data());
with data() returning a char*
for QT5, you should use fromCString() instead, as fromAscii() is deprecated, see https://bugreports.qt-project.org/browse/QTBUG-21872 https://bugreports.qt.io/browse/QTBUG-21872
You may find QString::fromUtf8() also useful.
For QByteArray input of "\010" and "\000",
QString::fromLocal8Bit(input, 1) returns "\010" and ""
QString::fromUtf8(input, 1) correctly returns "\010" and "\000".
Use QString::fromUtf16((ushort *)Data.data()), as shown in the following code example:
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// QByteArray to QString
// =====================
const char c_test[10] = {'t', '\0', 'e', '\0', 's', '\0', 't', '\0', '\0', '\0'};
QByteArray qba_test(QByteArray::fromRawData(c_test, 10));
qDebug().nospace().noquote() << "qba_test[" << qba_test << "]"; // Should see: qba_test[t
QString qstr_test = QString::fromUtf16((ushort *)qba_test.data());
qDebug().nospace().noquote() << "qstr_test[" << qstr_test << "]"; // Should see: qstr_test[test]
return a.exec();
}
This is an alternative solution to the one using QTextCodec. The code has been tested using Qt 5.4.
Qt 5.12 and up:
QString::fromStdString(byteArray.toStdString());