Qt array QString - qt

I get result from db by selectall query and I want save result in array and send it by socket.
db.open();
QSqlQuery *selectall = new QSqlQuery(db);
selectall->prepare("select * from phone_table");
selectall->exec();
selectall->first();
QString result;
QByteArray arrayresult;
int index = 0;
while (selectall->next())
{
index += 1;
// qint16 id = selectall->value(0).toString();
QString name_ = selectall->value(1).toString();
QString surname = selectall->value(2).toString();
QString phone_number = selectall->value(3).toString();
result = "*"+ name_+"*"+surname+"*"+phone_number;
arrayresult[index] = result;
}
I get this error binary '=' : no operator found which takes a right-hand operand of type 'const char [16]'

You are trying to set a QByteRef to a QString.
I think you may want a QList and to arrayresult.append(result).
Or else if you want one QByteArray with the concat of all results use arrayresult+= result.

You may build the QString you want to initialize QByteArray. To then convert from QString to QByteArray, you can do
QByteArray array_ = string_.toLatin1();
if encoding is Latin1.
You may alternatively use append
QByteArray & QByteArray::append ( const QString & str )
This is an overloaded function.
Appends the string str to this byte array. The Unicode data is
converted into 8-bit characters using QString::toAscii().
If the QString contains non-ASCII Unicode characters, using this
function can lead to loss of information. You can disable this
function by defining QT_NO_CAST_TO_ASCII when you compile your
applications. You then need to call QString::toAscii() (or
QString::toLatin1() or QString::toUtf8() or QString::toLocal8Bit())
explicitly if you want to convert the data to const char *.
append is doing the same as + operator.

You can do the following with the toLatin1() function of the QString.
// ...
QString result = QString( "*%1*%2*%3" ).arg( name_ )
.arg( surname )
.arg( phone_number );
QByteArray resultArray = result.toLatin1();
// Or ...
// QByteArray resultArray = result.toLocal8Bit();
// QByteArray resultArray = result.toUtf8();
And you shall use a QList< QByteArray > for containing the results, or you can just append the last result item to your final result object.

Related

QT String to char * adds extra characters

I have a qTextEdit that I grab the text from (QString) and convert to a char* with this code:
QString msgQText = ui->textMsg->toPlainText();
size_t textSize = (size_t)msgQText.size();
if (textSize > 139) {
textSize = 139;
}
unsigned char * msgText = (unsigned char *)malloc(textSize);
memcpy(msgText, msgQText.toLocal8Bit().data(), textSize);
msgText[textSize] = '\0';
if (textSize > 0) {
Msg * newTextMsg = new Msg;
newTextMsg->type = 1; // text message type
newTextMsg->bitrate = 0;
newTextMsg->samplerate = 0;
newTextMsg->bufSize = (int)textSize;
newTextMsg->len = 0;
newTextMsg->buf = (char *)malloc(textSize);
memcpy((char *)newTextMsg->buf, (char *)msgText, textSize);
lPushToEnd(sendMsgList, newTextMsg, sizeof(Msg));
ui->sendRecList->addItem((char *)newTextMsg->buf);
ui->textMsg->clear();
}
I put the text into a qListBox, but it shows up like
However, the character array, if I print it out, does not have the extra characters.
I have tried checking the "compile using UTF-8" option, but it doesn't make a difference.
Also, I send the text using RS232, and the receiver side also displays the extra characters.
The receiver code is here:
m_serial->waitForReadyRead(200);
const QByteArray data = m_serial->readAll();
if (data.size() > 0) {
qDebug() << "New serial data: " << data;
QString str = QString(data);
if (str.contains("0x6F8C32E90A")) {
qDebug() << "TEST SUCCESSFUL!";
}
return data.data();
} else {
return NULL;
}
There is a difference between the size of a QString and the size of the QByteArray returned by toLocal8Bit(). A QString contains unicode text stored as UTF-16, while a QByteArray is "just" a char[].
A QByteArray is null-terminated, so you do not need to add it manually.
As #GM pointed out: msgText[textSize] = '\0'; is undefined behavior. You are writing to the textSize + 1 position of the msgText array.
This position may be owned by something else and may be overwritten, so you end up with a non null terminated string.
This should work:
QByteArray bytes = msgQText.toLocal8Bit();
size_t textSize = (size_t)bytes.size() + 1; // Add 1 for the final '\0'
unsigned char * msgText = (unsigned char *) malloc(textSize);
memcpy(msgText, bytes.constData(), textSize);
Additional tips:
Prefer using const functions on Qt types that are copy-on-write, e.g. use QBytearray::constData() instead of QByteArray::data(). The non-const functions can cause a deep-copy of the object.
Do not use malloc() and other C-style functions if possible. Here you could do:
unsigned char * msgText = new unsigned char[textSize]; and later delete[] msgText;.
Prefer using C++ casts (static_cast, reinterpret_cast, etc.) instead of C-style casts.
You are making 2 copies of the text (2 calls to memcpy), given your code only 1 seem to be enough.

QString with special characters to const char*

I m trying to convert QString with special characters to const char* but I did not succeed. my function is:
void class::func(const QString& Name) // fileName = "â.tmp"
{
qDebug()<< Name; // display "â.tmp"
const char* cfileName = Name.toAscii().data();
qDebug() << cfileName; // display "a?.tmp"
}
qDebug()<< fileName display the true value that is "â.tmp" but after converting it to const a char*, I do not succeed to have the right value.
In the second time I try to use const char* cfileName = QString::fromUtf8(fileName.toAscii().data()); but I did not still have the right value, it display the same thing: "a?.tmp". How can I fix this thank you
due to convert QString to const char* :
QString str("hi lor!");
const char *s = str.toStdString().c_str();
msg.setText(QString::fromUtf8(s));
msg.exec();
EDIT: using QByteArray QString::toUtf8 () const is much better
QString string = "â.tmp";
const char* encodedString = string.toUtf8().data();
ORIGIONAL:
You probably need to use a codec, see http://qt-project.org/doc/qt-4.8/qtextcodec.html
something like this should work:
QString string = "â.tmp";
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QByteArray encodedString = codec->fromUnicode(string);
the documentation does not say what encoding types QDebug & QDebug::operator<< ( const char * s ) supports, it may be platform dependent, try verifying a correct conversion another. The problem may be in qDebug() or the stream it writes to.

QByteArray convert to/from unsigned char *

QByteArray inArray = " ... ";
unsigned char *in = convert1(inArray);
unsigned char *out;
someFunction(in, out);
QByteArray outArray = convert2(out);
the question is how can I correctly make these conversions (convert1 and convert2).
I cannot change someFunction(unsigned char *, unsigned char *), but I have to work with QByteArray here.
Qt has really great docs, you should use them.
If someFunction doesn't modify or store pointer to in data you can use this:
QByteArray inArray = " ... ";
unsigned char *out;
someFunction((unsigned char*)(inArray.data()), out);
QByteArray outArray((char*)out);
Otherwise you have to make a deep copy of the char* returned by QByteArray::data() (see the docs for code snippet).
if someFunction takes a const char* args then just use ConstData() or data() in QByteArray class.
if you need a char*, you can then use strdup(). This method is doing this
char *strdup (const char *s) {
char *d = malloc (strlen (s) + 1); // Space for length plus nul
if (d == NULL) return NULL; // No memory
strcpy (d,s); // Copy the characters
return d; // Return the new string
}
more info here: strdup() - what does it do in C?

C macro to C++\Qt

I have the following c macro from the libpurple yahoo plugin:
#define yahoo_put16(buf, data) ( \
(*(buf) = (unsigned char)((data)>>8)&0xff), \
(*((buf)+1) = (unsigned char)(data)&0xff), \
2)
I want to implement the same as a function in my class witch would receive as a parameter a quint16 value and return it as a QByteArray
I have the following but i don't seem to get the same result as with the macro above.
QByteArray YahooPacket::packQuint16(quint16 value) const
{
QByteArray data;
data.append(QByteArray::number((value >> 8) & 0xFF));
data.append(QByteArray::number(value & 0xFF));
return data;
}
How would i do to implement my function?
QByteArray::number() creates the printable (string) version of the number which is probably not what you want. Use the QByteArray constructor that takes a buffer pointer and a size parameter. I think this will do what you want.
QByteArray YahooPacket::packQuint16(quint16 value) const
{
QByteArray data;
data.append(QByteArray(((char*)&value)+1,1));
data.append(QByteArray((char*)&value,1));
return data;
}

How to convert LPTSTR to QString

Hi can anyone help me to convert LPTSTR to QString
You will see in the docs that Qstring provides static function to convert from both ascii and Unicode strings:
QString fromAscii ( const char *
ascii, int len = -1 )
QString fromLatin1 ( const char *
chars, int len = -1 )
QString fromUtf8 ( const char * utf8,
int len = -1 )
QString fromLocal8Bit ( const char *
local8Bit, int len = -1 )
QString fromUcs2 ( const unsigned
short * str )
Check whether you are using ascii or unicode and pick your poison.
QString::fromWCharArray is what worked for me.
To convert QString to LPTSTR or LPCTSTR:
QString src;
LPTSTR dest=(LPTSTR)src.utf16();
to convert from LPTSTR or LPCTSTR to QString :
src=QString::fromUtf16(dest);
The solution expects that your LPTSTR array is null-terminated.
STRRET str; // it had been filled by a winapi function
// str.pOleStr is LPWSTR, i.e. wchar_t* field of the union STRRET
// LPWSTR is the same as LPTSTR (see further)
QString result{QString::fromWCharArray(str.pOleStr)};
As shown below, STRRET is a union, one of representations of which (named pOleStr) has type wchar_t*.
As far as I understand, when one gets this STRRET filled by a Winapi function (like e.g. IShellFolder::GetDisplayNameOf()), it's a normal null-terminated wide string. So it can be supplied to QString::fromWCharArray(const wchar_t *string). The function will preserve the input wchar_t-array as it is and will just create a new copy inside a new QString. So overall, I think the method in my answer is quite safe as far as you know that your const wchar_t * is ended with a \0-wide-character.
// shtypes.h
typedef struct _STRRET
{
UINT uType;
/* [switch_is][switch_type] */ union
{
/* [case()][string] */ LPWSTR pOleStr;
/* [case()] */ UINT uOffset;
/* [case()] */ char cStr[ 260 ];
} DUMMYUNIONNAME;
} STRRET;
// winnt.h
typedef _Null_terminated_ WCHAR *NWPSTR, *LPWSTR, *PWSTR;
typedef LPWSTR PTSTR, LPTSTR;
Use QString::fromUcs2 to convert strings.
This is woking fine
QString str("ddddd");
LPCTSTR lstr = (LPCTSTR)str.data();

Resources