106

I was trying to convert a QString to char* type by the following methods, but they don't seem to work.

//QLineEdit *line=new QLineEdit();{just to describe what is line here}

QString temp=line->text();
char *str=(char *)malloc(10);
QByteArray ba=temp.toLatin1();
strcpy(str,ba.data());

Can you elaborate the possible flaw with this method, or give an alternative method?

lpapp
  • 47,035
  • 38
  • 95
  • 127
mawia
  • 8,513
  • 13
  • 45
  • 57

10 Answers10

123

Well, the Qt FAQ says:

int main(int argc, char **argv)
{
 QApplication app(argc, argv);
  QString str1 = "Test";
  QByteArray ba = str1.toLocal8Bit();
  const char *c_str2 = ba.data();
  printf("str2: %s", c_str2);
  return app.exec();
}

So perhaps you're having other problems. How exactly doesn't this work?

bur
  • 532
  • 2
  • 17
Eli Bendersky
  • 231,995
  • 78
  • 333
  • 394
  • 11
    `const char*` and `char*` are not the same type. – Lightness Races in Orbit Nov 15 '12 at 22:12
  • 4
    @LightnessRacesinOrbit: writing to QString's contents without it knowing is a horrible idea, hence of course `const char*` is what can really be obtained. The user is free to copy the data to a writable buffer. – Eli Bendersky Nov 16 '12 at 14:28
  • 1
    I completely agree. However, the question asked about `char*`, not `char const*`, and your answer simply ignores that fact without mention. – Lightness Races in Orbit Nov 16 '12 at 16:48
  • 5
    @LightnessRacesinOrbit: sometimes the best answer is to unask the question. In other words, to point out that it's not asking the right thing. This answer was accepted by the question poster, so I suppose it hit its target – Eli Bendersky Nov 16 '12 at 23:38
  • There is No difference between printf("str2: %s",(const char *) ba.data()); and printf("str2: %s", ba.data()); Wrong Solution – sam May 29 '16 at 08:17
  • 2
    seems like the FAQ has been updated to use `toLocal8Bit()`? – Larry Mar 26 '18 at 18:42
  • 1
    This can be shortened to `QString str = "Test"; const char *c_str = str.toLocal8Bit().data();`. – bur Oct 15 '18 at 14:26
  • why this is accepted answer ??? there is difference between const char * and char * – user889030 Jul 10 '19 at 12:35
  • @user889030 note that this answer is from 9 years ago, and much has changed in Qt. SO answers don't always stand the test of time well for old versions of libraries – Eli Bendersky Jul 10 '19 at 17:20
  • May not be cross-platform solution since the local8Bit encoding can be different depending on the platform. Writing to a file a ba.toLocal8Bit() and then doing fromLocal8Bit from another platform can give unexpected result if the local is different. – gpalex Oct 07 '19 at 12:42
  • @bur - Can it? The `QByteArray` returned by `toLocal8Bit()` will go out of scope at the end of the statement, leaving `c_str` pointing to undefined data. (But shortening it further to `printf("str2: %s", str.toLocal8Bit().data());` will work, because the temporary `QByteArray` remains in scope until `printf()` returns.) – Jeremy Jul 01 '20 at 13:40
58

Maybe

my_qstring.toStdString().c_str();

or safer, as Federico points out:

std::string str = my_qstring.toStdString();
const char* p = str.c_str();

It's far from optimal, but will do the work.

davidnr
  • 3,329
  • 2
  • 17
  • 14
  • 3
    This will mess up Unicode characters. A Unicode-friendly solution: http://stackoverflow.com/a/4644922/238387 – jlstrecker Sep 18 '12 at 19:35
  • 21
    This method is very dangerous and should not be used: `toStdString()` return a new `std::string` object and then the pointer to internal data `const char *` is obtained. However, the string object is immediately destroyed after this statement, so the result pointer probably does not have a valid address if you use it in a subsequent statement. – ocirocir Mar 06 '16 at 12:32
  • 1
    @RicoRico It's not the method `toStdString()` that's dangerous; it's the use of raw pointers. Or, more specifically, the use of raw pointers from objects whose scopes aren't well-understood. – notlesh Oct 20 '19 at 20:23
  • Specifically C++ temporaries normally live until the end of the statement that creates them. So the first form in the answer is ok if it's used in-line in a function call (assuming the function doesn't store the pointer for future use) but it's not ok if it's assigned to a variable. – plugwash Nov 08 '19 at 19:04
55

The easiest way to convert a QString to char* is qPrintable(const QString& str), which is a macro expanding to str.toLocal8Bit().constData().

KernelPanic
  • 2,316
  • 6
  • 37
  • 77
Robert
  • 599
  • 4
  • 5
  • Why isn't this a more popular answer? I just learned about this by accident while poking around the Qt source, and that's exactly what they do. – Phlucious Jun 22 '16 at 15:59
  • 6
    @Phlucious, because: 1) `qPrintable` returns `const char*` not `char*`, `str.toLocal8Bit().data()` returns `char*`. 2) The pointer to `const char*` becomes invalid as soon as you hit a semicolon in the statement where `qPrintable` was used. So `const char* c_ptr = s.toLocal8Bit().constData();` does not make any sense. – WindyFields Sep 14 '17 at 03:21
  • 1
    @Phlucious thanks you are life saver :) these all top voted answers are wrong , Question is about char and they are returning const char* – user889030 Jul 10 '19 at 12:48
  • Is `qPrintable` output guaranteed to be zero terminated? – Giovanni Cerretani Mar 12 '20 at 09:59
  • @WindyFields - As warned in the `qPrintable()` description: "The char pointer will be invalid after the statement in which qPrintable() is used." – Jeremy Jul 01 '20 at 13:52
7

David's answer works fine if you're only using it for outputting to a file or displaying on the screen, but if a function or library requires a char* for parsing, then this method works best:

// copy QString to char*
QString filename = "C:\dev\file.xml";
char* cstr;
string fname = filename.toStdString();
cstr = new char [fname.size()+1];
strcpy( cstr, fname.c_str() );

// function that requires a char* parameter
parseXML(cstr);
Alex
  • 1,020
  • 17
  • 26
6

EDITED

this way also works

QString str ("Something");

char* ch = str.toStdString().C_str();
Shanks
  • 613
  • 5
  • 20
3

Your string may contain non Latin1 characters, which leads to undefined data. It depends of what you mean by "it deosn't seem to work".

gregseth
  • 12,078
  • 14
  • 53
  • 92
2

the Correct Solution Would be like this

   QString k;
   k = "CRAZYYYQT";
   char ab[16];
   sprintf(ab,"%s",(const char *)((QByteArray)(k.toLatin1()).data()) );
   sprintf(ab,"%s",(const char *)((QByteArray)(k.toStdString()).data()));  
   sprintf(ab,"%s",(const char *)k.toStdString().c_str()  );
   qDebug()<<"--->"<<ab<<"<---";
sam
  • 1,186
  • 1
  • 18
  • 27
2

If your string contains non-ASCII characters - it's better to do it this way: s.toUtf8().data() (or s->toUtf8().data())

AlexDarkVoid
  • 341
  • 1
  • 11
1

Qt provides the simplest API

const char *qPrintable(const QString &str)
const char *qUtf8Printable(const QString &str)

If you want non-const data pointer use

str.toLocal8Bit().data()
str.toUtf8().data()
JBES
  • 1,321
  • 9
  • 16
0

It is a viable way to use std::vector as an intermediate container:

QString dataSrc("FooBar");
QString databa = dataSrc.toUtf8();
std::vector<char> data(databa.begin(), databa.end());
char* pDataChar = data.data();
TCH
  • 51
  • 1
  • 4