PDA

View Full Version : char* from QString



bruccutler
25th January 2007, 19:09
Hello,
Another really newbie question. What is the appropriate way to get a char * pointer from a QString object? I'm using object.toLocal8Bit().constData(), but doesn't always work (or maybe it doesn't work at all).
- BC

wysota
25th January 2007, 19:17
It works, just remember it is a const char*. BTW. there is a macro which is a shortcut to the above mentioned combination:

QString str = "xxxx";
printf("%s", qPrintable(str));

jacek
25th January 2007, 19:24
Please, search the forum before you ask a question. This topic was already discussed here: http://www.qtcentre.org/forum/f-qt-programming-2/t-qstring-to-char-not-converting-3211.html

bruccutler
25th January 2007, 20:00
Please, search the forum before you ask a question. This topic was already discussed here: http://www.qtcentre.org/forum/f-qt-programming-2/t-qstring-to-char-not-converting-3211.html

So, will the qPrintable work, or is the only (best) way to create a QByteArray that doesn't go out of scope? I looked at the previous post and can I assume yours is the only way to do this?

Incidentally, I find the Qt site difficult to search. This forum is excellent, however!
- BC

jpn
25th January 2007, 20:04
Incidentally, I find the Qt site difficult to search.
Have you tried Qt Assistant's indexing and searching facilities? In my opinion it's superior.. ;)

jacek
25th January 2007, 20:18
So, will the qPrintable work, or is the only (best) way to create a QByteArray that doesn't go out of scope? I looked at the previous post and can I assume yours is the only way to do this?
qPrintable() will only work as a function parameter, so either use:
char *cstr = qstrdup( qPrintable( str ) );
...
delete [] cstr;
or
QByteArray ba( str.toLocal8bit() );
const char *cstr = ba.constData(); // cstr is valid as long as ba is alive

bruccutler
26th January 2007, 14:49
Thanks. I've gone with the second method. Thanks for the help and I apologize that I didn't do a search first.

sunil.thaha
1st February 2007, 08:48
From the Faq



You can use toLatin1() to get a byte array and then call data() on that one which will give you a char*, i.e
toLatin1().data() // Is this wrong ??

http://doc.trolltech.com/4.2/qstring.html#toLatin1

To convert a QString to a char* you can do the following:
QString(QLatin1String(charstringhere))

See the documentation:

http://doc.trolltech.com/4.2/qlatin1string.html
So is the Faq wrong ??

I have tried this program


#include <iostream>
#include <QString>

int main(){
QString str = "Sunil Thaha";
std::cout << str.toLatin1().data() << std::endl;

const char *charPointer = str.toLatin1().data();
std::cout << charPointer << std::endl;

if( charPointer == str.toLatin1().data() ){
std::cout<< "Still pointing to same location ";
}
return 0;
}


My results confirms with the Faq... I am able to get a const pointer to the data() and further calls returns the same memory address ??:confused: Both Wiki and jaceks post discourages us from using this. So who is right here ?

wysota
1st February 2007, 11:11
str.toLatin1().data()
This creates a temporary object (QByteArray) and returns a pointer to its data, but the temporary object is deleted immediately. The memory is not cleared, the compiler does some optimisations, etc. - the bottom line is the data IS there, but only because you're lucky. If you try to use the pointer after some time the byte array is deleted, you'll eventually receive trash which may cause your app to malfunction. This is strictly related to memory management on your system and to the compiler used. It is not safe to use such constructions in terms of the C++ standard.

You can think of it as the same as if you'd send a signal accross threads in Qt3 - basically it works (unfortunately only "most of the time"), but it doesn't mean that the code is correct.

sunil.thaha
1st February 2007, 11:25
Please refer to this Faq http://www.trolltech.com/developer/knowledgebase/faq.2007-01-30.9032238253/

How can we ask for correction ?

wysota
1st February 2007, 11:40
There is nothing wrong in that entry, besides it seems to be an internal Trolltech tool and I'm sure they know about the quirk of storing the volatile pointer.

sunil.thaha
1st February 2007, 11:46
There is nothing wrong in that entry,

But all the posts above are against it isn't it ? And that being an official Faq; should not be pointing in a wrong direction

wysota
1st February 2007, 12:44
But all the posts above are against it isn't it ?

No, it doesn't say anything about storing the data pointer and only referring to it after the temporary object is destroyed is in violation with the specification. This is a perfectly legitimate statement:


QString str = "xxxx";
printf("%s\n", str.toLocal8Bit().data());

whereas this one is not:


QString str = "xxxx";
char *ptr = str.toLocal8Bit().data();
printf("%s\n", ptr);

If you want to store the pointer, keep the byte array intact:

QString str = "xxxx";
QByteArray ba = str.toLocal8Bit();
char *ptr = ba.data(); // this is valid as long as "ba" is
//...
printf("%s\n", ptr);

sunil.thaha
1st February 2007, 12:59
Waw !!

Beautiful answer... Thanks a lot for the time and patience.
Long live QtCentre

sunil.thaha
13th February 2007, 09:53
After this discussions and the subsequent discussion with Qt-Interest mailing list. I had requested the change told above. Trolltech has accepted the change request and has modified the faq

Here is the link to that

http://www.trolltech.com/developer/knowledgebase/faq.2007-01-30.9032238253


Thanks once again.

VireX
14th February 2007, 01:47
Btw, jacek wrote delete [] cstr, but you dont need to delete a pointer unless you initialized it with new keyword.

sunil.thaha
14th February 2007, 06:36
From the docs:


char * qstrdup ( const char * src ) Returns a duplicate string.
Allocates space for a copy of src, copies it, and returns a pointer to the copy. If src is 0, it immediately returns 0.
Ownership is passed to the caller, so the returned string must be deleted using delete[]