QString to char* conversion
-
Hi,
I must use library written in "C" in my project. so I need do QString to char* conversion, I try like this:
QString text; char* ch = text.toStdString().C_str();
But I get error:
c56sdkapp.cpp:35:35: No member named 'C_str' in 'std::basic_string<char>'
How can this conversion i other way?
-
@Chris-Kawa said in QString to char* conversion:
@Damian7546 Well it doesn't work because you're assigning std::string to char* variable. It doesn't make any sense.
You have to check what encoding the function fun1 expects in its pszTxt parameter.
If its local codepage then
fun1(hDocument, text.toLocal8Bit().constData());If it's UTF-8 then
fun1(hDocument, text.toUtf8().constData());But in this way doesn't works. ->
No matching fuction for call to fun1
@Damian7546 Ugh, right, the function takes PSTR, which is a non-const pointer. It's not nice of it, but it just means you have to give it a non-const pointer i.e.
fun1(hDocument, text.toLocal8Bit().data());
or
fun1(hDocument, text.toUtf8().data());
Just keep in mind that since it takes a non-const pointer it indicates that it can change the content of that string, which, if it does, will be lost, since it's a temporary.
-
It's
c_str()
, lowercase "c" https://en.cppreference.com/w/cpp/string/basic_string/c_str -
ok, but still doesn't works
void C56SdkApp::PrintTest(QString text) { char* ch = text.toStdString().c_str(); }
Error:
c56sdkapp.cpp:36:11: Cannot initialize a variable of type 'char *' with an rvalue of type 'const char *'
so what can I do ?
-
ok, but still doesn't works
void C56SdkApp::PrintTest(QString text) { char* ch = text.toStdString().c_str(); }
Error:
c56sdkapp.cpp:36:11: Cannot initialize a variable of type 'char *' with an rvalue of type 'const char *'
so what can I do ?
@Damian7546 said in QString to char* conversion:
ok, but still doesn't works
Error: c56sdkapp.cpp:36:11: Cannot initialize a variable of type 'char *' with an rvalue of type 'const char *'
so what can I do ?
Use
const char* ch = text.toStdString().c_str();
-
const char* ch
will compile, but you can't use that afterwards.toStdString
creates a temporary, which is destroysed after;
, so your variable points to released memory.If you want to use it in some function that takes a
const char*
as parameter you can do it either like this:SomeFunction(text.toStdString().c_str()); //temporary is in scope still
or like this:
std::string s = text.toStdString(); SomeFunction(s.c_str());
but you can't do this:
const char* ch = text.toStdString().c_str(); //ch is pointing to garbage at this point SomeFunction(ch);
-
const char* ch
will compile, but you can't use that afterwards.toStdString
creates a temporary, which is destroysed after;
, so your variable points to released memory.If you want to use it in some function that takes a
const char*
as parameter you can do it either like this:SomeFunction(text.toStdString().c_str()); //temporary is in scope still
or like this:
std::string s = text.toStdString(); SomeFunction(s.c_str());
but you can't do this:
const char* ch = text.toStdString().c_str(); //ch is pointing to garbage at this point SomeFunction(ch);
@Chris-Kawa
Why is the OP usingtoStdString.c_str()
at all? What about, say,toUtf8().constData()
ortoLocal8Bit().constData()
, are these any better/simpler/quicker? -
@Chris-Kawa
Why is the OP usingtoStdString.c_str()
at all? What about, say,toUtf8().constData()
ortoLocal8Bit().constData()
, are these any better/simpler/quicker?@JonB I don't know if they're better/simpler/quicker. I haven't measured. But one benefit would certainly be that they don't use std library to achieve the same result. Why use two libraries when you can do the same with one.
-
@JonB I don't know if they're better/simpler/quicker. I haven't measured. But one benefit would certainly be that they don't use std library to achieve the same result. Why use two libraries when you can do the same with one.
@Chris-Kawa
I'm relying on you to tell me/him! I have given up on trying to understand character encodings, it's too difficult, tg I'm English! But I think I read thattoUtf8()
would be for Linux whiletoLocal8Bit()
(ortoLatin()
??) is for Windows, does that mean it's not platform independent whiletoStdString()
is cross-platform?? Sigh.... -
you can try this:
QString str="Something"; qDebug()<<str.toLocal8Bit().constData();
or
QString str="Something"; const char *ch=str.toLocal8Bit().constData(); qDebug()<<ch;
-
you can try this:
QString str="Something"; qDebug()<<str.toLocal8Bit().constData();
or
QString str="Something"; const char *ch=str.toLocal8Bit().constData(); qDebug()<<ch;
@Emre-MUTLU
Yep, I agree,toLocal8Bit()
seems to be the way to go. Maybe that's allstd::string
does anyway? -
i guess so yes
-
i guess so yes
@Emre-MUTLU As I said above you can't do this:
QString str="Something"; const char *ch=str.toLocal8Bit().constData(); qDebug()<<ch;
toLocal8Bit
returns a temporary object.As to encodings - std::string does not dictate encoding. It's just a bag of bytes.
toStdString
andtoUtf8
are the same i.e. return an UTF-8 string, just different containers. The first one is std::string and the other QByteArray.toLocal8bit
uses system locale, meaning the result will be different on different machines. Could be utf-8 on Linux, ISO 8859-1 or Windows-1252 in some European countries, some crazy stuff in asian languages or whatever the local encoding is on your machine. Note that QString is UTF-16 while local encoding can be fixed size 8bit, so usingtoLocal8Bit
can be a lossy conversion. The docs say if any character can't be converted the result is undefined.Which to use depends not on the functions themselves but on what you plan to do with the result. If you want to pass it to a function that accepts UTF-8 then use
toUtf8()
. If it's a system call that uses local codepage thentoLocal8Bit
. If it's a wide character WinAPI thentoWCharArray
etc. -
@Emre-MUTLU As I said above you can't do this:
QString str="Something"; const char *ch=str.toLocal8Bit().constData(); qDebug()<<ch;
toLocal8Bit
returns a temporary object.As to encodings - std::string does not dictate encoding. It's just a bag of bytes.
toStdString
andtoUtf8
are the same i.e. return an UTF-8 string, just different containers. The first one is std::string and the other QByteArray.toLocal8bit
uses system locale, meaning the result will be different on different machines. Could be utf-8 on Linux, ISO 8859-1 or Windows-1252 in some European countries, some crazy stuff in asian languages or whatever the local encoding is on your machine. Note that QString is UTF-16 while local encoding can be fixed size 8bit, so usingtoLocal8Bit
can be a lossy conversion. The docs say if any character can't be converted the result is undefined.Which to use depends not on the functions themselves but on what you plan to do with the result. If you want to pass it to a function that accepts UTF-8 then use
toUtf8()
. If it's a system call that uses local codepage thentoLocal8Bit
. If it's a wide character WinAPI thentoWCharArray
etc.It's also worth mentioning that std::string was invented when UTF was not a common thing, so basically it sucks for anything that's multibyte. It can hold it fine, but methods like
size()
return the number of bytes, not characters. To get a length (in characters) of a multibyte string contained in std::string you have to use external function that understands multibyte. As such std::string is best suited for 8bit encodings, but technically is not limited to them. -
@Emre-MUTLU
Yep, I agree,toLocal8Bit()
seems to be the way to go. Maybe that's allstd::string
does anyway?@JonB said in QString to char* conversion:
@Emre-MUTLU
Yep, I agree,toLocal8Bit()
seems to be the way to go. Maybe that's allstd::string
does anyway?std::string is encoding agnostic, so the encoding is the one you choose to use.
ISO-8859 tried to be a "de facto standard" at least on windows and linux, but apple used MacRoman.
Before unicode/utf8 transcoding between OS was pure nightmare. -
@Emre-MUTLU As I said above you can't do this:
QString str="Something"; const char *ch=str.toLocal8Bit().constData(); qDebug()<<ch;
toLocal8Bit
returns a temporary object.As to encodings - std::string does not dictate encoding. It's just a bag of bytes.
toStdString
andtoUtf8
are the same i.e. return an UTF-8 string, just different containers. The first one is std::string and the other QByteArray.toLocal8bit
uses system locale, meaning the result will be different on different machines. Could be utf-8 on Linux, ISO 8859-1 or Windows-1252 in some European countries, some crazy stuff in asian languages or whatever the local encoding is on your machine. Note that QString is UTF-16 while local encoding can be fixed size 8bit, so usingtoLocal8Bit
can be a lossy conversion. The docs say if any character can't be converted the result is undefined.Which to use depends not on the functions themselves but on what you plan to do with the result. If you want to pass it to a function that accepts UTF-8 then use
toUtf8()
. If it's a system call that uses local codepage thentoLocal8Bit
. If it's a wide character WinAPI thentoWCharArray
etc.@Chris-Kawa said in QString to char* conversion:
toLocal8Bit
returns a temporary object.I'm beginning to sense that all (not just some of) the
QString::to...()
methods return a temporary object. I wish the docs said so!!!! -
@Chris-Kawa said in QString to char* conversion:
toLocal8Bit
returns a temporary object.I'm beginning to sense that all (not just some of) the
QString::to...()
methods return a temporary object. I wish the docs said so!!!!@JonB Well most functions return temporaries e.g.
std::string foo() { return "something"; }
is a temporary. It just depends on how you use them. The docs would have to say that on everything that doesn't return a pointer or a reference.foo(); // returns an r-value (temporary) that is never used, so destroyed immediately
SomeFunction(foo()); //returns an r-value and passes it into the function. Lives in the scope of the function call.
std::string s = foo(); //returns an r-value and assigns it to a new variable.
in this last case RVO also kicks in.
-
@Chris-Kawa said in QString to char* conversion:
toLocal8Bit
returns a temporary object.I'm beginning to sense that all (not just some of) the
QString::to...()
methods return a temporary object. I wish the docs said so!!!!@JonB said in QString to char* conversion:
I wish the docs said so!!!!
As soon as an object is returned from any function (even a plain C function) it's a temporary until you assign it to a local variable.
-
@JonB said in QString to char* conversion:
@Emre-MUTLU
Yep, I agree,toLocal8Bit()
seems to be the way to go. Maybe that's allstd::string
does anyway?std::string is encoding agnostic, so the encoding is the one you choose to use.
ISO-8859 tried to be a "de facto standard" at least on windows and linux, but apple used MacRoman.
Before unicode/utf8 transcoding between OS was pure nightmare.@mpergand said in QString to char* conversion:
std::string is encoding agnostic, so the encoding is the one you choose to use.
And Qt defines that every std::string created from QString is UTF-8 encoded:
inline std::string QString::toStdString() const { return toUtf8().toStdString(); }
Even QString::toLocal8Bit() on Linux assumes the locale is UTF-8 - encoded without looking at the real locale, on Window the locale is respected.
-
const char* ch
will compile, but you can't use that afterwards.toStdString
creates a temporary, which is destroysed after;
, so your variable points to released memory.If you want to use it in some function that takes a
const char*
as parameter you can do it either like this:SomeFunction(text.toStdString().c_str()); //temporary is in scope still
or like this:
std::string s = text.toStdString(); SomeFunction(s.c_str());
but you can't do this:
const char* ch = text.toStdString().c_str(); //ch is pointing to garbage at this point SomeFunction(ch);
@Chris-Kawa
I would like to passQString
topszTxt
parameter in this function:
fun1(HANDLE hDocument, PSTR pszTxt)
Below doesn't works:
void C56SdkApp::PrintTest(QString text) { char* ch = text.toUtf8().toStdString(); fun1(hDocument, ch ); }
-
@Damian7546 Well it doesn't work because you're assigning std::string to char* variable. It doesn't make any sense.
You have to check what encoding the function fun1 expects in its pszTxt parameter.
If its local codepage thenfun1(hDocument, text.toLocal8Bit().constData());
If it's UTF-8 then
fun1(hDocument, text.toUtf8().constData());