PDA

View Full Version : QString to char* not converting



DPinLV
2nd August 2006, 04:10
Hi,

I see some suggestions for how to convert a QString to a char* (or const char*), but when I try them I get bad data.

For instance, I try this:

QString doh = ("Blah, blah, blah");
cout << "The String " << qPrintable(doh) << endl;

// Convert to char*
const char *message = doh.toLocal8Bit ().constData (); //<--- DOES NOT WORK!!
cout << "The Message is " << message << endl;

and the output looks like as follows:

The String Blah, blah, blah
The Message is ▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌

Then, if I try this the output is the same:

QString doh = ("Blah, blah, blah");
cout << "The String " << qPrintable(doh) << endl;

// Convert to char*
const char *message = qPrintable(doh); //<--- DOES NOT WORK!!
cout << "The Message is " << message << endl;

The only way I get legit output is doing the following:

QString doh = ("Blah, blah, blah");
cout << "The String " << qPrintable(doh) << endl;

// Convert to char*
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QByteArray encodedString = codec->fromUnicode(doh);
const char *message = encodedString.constData ();
cout << "The Message is " << message << endl;

The output is then;

The String Blah, blah, blah
The Message is Blah, blah, blah

This can't be the cleanest way to accomplish getting the proper character string into my char*, can it? :confused:

Thanks,
Derrick

bood
2nd August 2006, 04:32
what about QString::ascii() ?

vishva
2nd August 2006, 05:37
hi,

just try this code,

QString str=" ";
char *st=qStrdup(qPrintable(str));

it convert QString to cons char or char *.

sumsin
2nd August 2006, 05:42
try QString's function latin1()

DPinLV
2nd August 2006, 17:52
Thanks all,

The only solution that gave me the proper message was:

qStrdup(qPrintable(str));

All of the others: toLatin, toAscii, and qPrintable, still printed the garbage data.

Thanks.

Methedrine
2nd August 2006, 22:52
or you could do



QString foo("bar");
char *baz = foo.toStdString().c_str()

jacek
2nd August 2006, 23:00
or you could do



QString foo("bar");
char *baz = foo.toStdString().c_str()

And it would fail for the same reason as other methods --- you create a temporary std::string, obtain a pointer to its internal data and then... std::string gets destroyed leaving a dangling pointer.

DPinLV
2nd August 2006, 23:01
Methedrine,

Thanks for the suggestion but for some reason my char* string appears to contain 16bit code. I also had to change a few things to make it compile.
First of all I tried this:

QString foo("bar");
char *baz = (char*)foo.toStdString().c_str();
cout << "The Message is " << baz << end

Then I tried this:

QString foo("bar");
const char *baz = foo.toStdString().c_str();
cout << "The Message is " << baz << end

In both cases, it did not work. This is the only conversion that works for me.

QString doh("Oops");
char* message = strdup(qPrintable(doh));
cout << "The Message is " << message << endl;

Byngl
3rd August 2006, 16:11
How about this?


char* message = doh.toLatin1().data();

jacek
3rd August 2006, 16:20
How about this?
char* message = doh.toLatin1().data();
The same problem. QString::toLatin1() returns QByteArray, which will be destroyed just after that line, so either you have to immediately create a copy of that char * or use:
QByteArray ba( doh.toLatin1() );
char *message = ba.data(); // message is valid as long as ba exists.

DPinLV
3rd August 2006, 18:14
Jacek,

Can you point me to some documentation that explains QStrings and QByteArrays better? Because I don't see why the byte array should be deleted here since it (or it's pointer) is still in scope, no?

char* message = doh.toLatin1().data();

The QByteArray help says, "QByteArray makes a deep copy of the const char * data, so you can modify it later without experiencing side effects", so shouldn't it be available to me to display? :confused:

This example also is confusing because I think both cases should show the same data.

QString qbar ("Bar");
cout << "Bar string: " << qbar.toAscii ().data () << endl; // Displays Bar
char* copy_qbar = qbar.toAscii ().data ();
cout << "Bar string: " << copy_qbar << endl; // Displays garbage

Thanks.

jacek
3rd August 2006, 19:22
I don't see why the byte array should be deleted here since it (or it's pointer) is still in scope, no?
The pointer is in scope, but the temporary QByteArray isn't. QString::toLatin1() returns a completely new QByteArray object --- not some reference to an internal buffer. On the other hand QByteArray::data() returns a pointer to internal data of that QByteArray, so if it gets destroyed, that pointer will be invalid.


The QByteArray help says, "QByteArray makes a deep copy of the const char * data, so you can modify it later without experiencing side effects", so shouldn't it be available to me to display?
It also says:
The pointer remains valid as long as the byte array isn't reallocated.
You should use QString::toLatin1() this way:

QString str( "some string" );
QByteArray ba( str.toLatin1() );
char *cstr = ba.data(); // you can use cstr as long as ba exist
but you do it like this:

char *cstr = str.toLatin1().data(); // wrong
this uses a temporary QByteArray that ceases to exist immediately, so the workaround is to copy that string:

char *cstr = qstrdup( str.toLatin1().data() ); // ok, but remember to delete cstr

DPinLV
3rd August 2006, 19:44
Jacek,

That clears some things up, thanks, you've been a great help.

Derrick

lum
4th August 2006, 12:04
const char * data () const (obsolete)

jacek
4th August 2006, 12:10
const char * data () const (obsolete)
It was available in Qt3, but this thread is about Qt4.

Methedrine
6th August 2006, 11:58
Methedrine,

Thanks for the suggestion but for some reason my char* string appears to contain 16bit code.

Then you are looking for .toStdWString().c_str() or however it's cased.

jacek
6th August 2006, 12:06
Then you are looking for .toStdWString().c_str() or however it's cased.
This also suffers from the same problem as other .toX().pointerToInternalData() constructs.

Methedrine
6th August 2006, 12:15
This also suffers from the same problem as other .toX().pointerToInternalData() constructs.

Sorry, my mistake. I got his problem wrong :o