QString to char* conversion - c++

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?

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?

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.

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

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);

EDITED
this way also works
QString str ("Something");
char* ch = str.toStdString().C_str();

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".

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

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<<"<---";

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()

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();

Related

QString formatting will not work qDebug

I try to avoid mixed QString and char* types in a QT program. I have a conversation function that returns a pointer of the data inside the QString, but I get very strange results. Whats wrong with this code?
Compiler and environment gcc (Debian 4.9.2-10) 4.9.2
Flags via qmake: QMAKE_CXXFLAGS += -std=c++11
Code snippet:
#include <QCoreApplication>
#include <iostream>
#define PCH(m) ( m.toAscii().data() )
// get the pointer short scripted
const char* CH(QString msg) {
const char* res = msg.toAscii().data();
return res;
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
const QString qformat = "%s does not work!";
const QString qvalue = "embedding";
// Works not
qDebug(CH(qformat), CH(qvalue));
// Works
qDebug(qformat.toAscii().data(), qvalue.toAscii().data());
// Works too but macro
qDebug(PCH(qformat), PCH(qvalue));
return app.exec();
}
Results
%s does not work! does not work!
embedding does not work!
embedding does not work!
Here you are copying QString to function, and return pointer to already destroyed data inside function. This is known undefined behavior, since you are returning pointer to garbage. Return QString.
const char* CH(QString msg) {
const char* res = msg.toAscii().data();
return res;
}
You should be using qDebug() and the formatting mechanism built into QString itself. You should also use QStringLiteral instead of depending on default string conversions - after all you've stated that you care about such things:
#include <QtCore>
int main()
{
const auto qformat = QStringLiteral("%1 does work!");
const auto qvalue = QStringLiteral("embedding");
qDebug() << qformat.arg(qvalue);
qDebug() << qformat.arg(0x7A01173C2, 0, 16);
}
The QStringLiteral, used on modern compilers, does not create an 8-bit C-string. It assembles a binary internal representation of a QString at compile time, and stores it in a read-only memory section of your executable. This is the only way to avoid runtime costs of string encoding.
There is no benefit whatsoever in doing a roundtrip via QString if you already have UTF8 encoded string literals or C-style strings that are UTF8 encoded. If you need to use C-style strings/string literals, use them directly with qDebug:
#include <QtCore>
int main() {
const char format[] = "%s does not work!";
const char value[] = "embedding";
qDebug(format, value);
}
If you need to pass temporary C-style strings, use QByteArray, but that's really a lot of code with very little to show for it - it's so verbose as to have a very bad code smell. So don't do it like this:
#include <QtCore>
QByteArray CH(const QString &msg) {
return msg.toLocal8Bit();
}
int main()
{
auto qformat = QStringLiteral("%s does work!");
auto qvalue = QStringLiteral("embedding");
qDebug(CH(qformat).constData(), CH(qvalue).constData());
}

Cannot Convert QString to const Char * [duplicate]

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?
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?
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.
The easiest way to convert a QString to char* is qPrintable(const QString& str),
which is a macro expanding to str.toLocal8Bit().constData().
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);
EDITED
this way also works
QString str ("Something");
char* ch = str.toStdString().C_str();
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".
If your string contains non-ASCII characters - it's better to do it this way:
s.toUtf8().data() (or s->toUtf8().data())
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<<"<---";
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()
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();

Is it possible to initialize a const char* member as a composite of char arrays?

This should be simple:
I have a static const char* member on my class. I would like to initialize it as a composite string. For example:
const char* s_firstPart = "Hello I'm the first part.";
const char* s_secondPart = "I'm the second part.;
struct MyClass
{
static const char* s_theFinalString;
}
const char* MyClass::s_theFinalString = "Here is the string: " \
+ s_firstPart ++ s_secondPart; // obviously this won't compile
My question is: Is there a way of initializing const char* members as composite char arrays?
The correct answer came from #dauphic in the comments:
No, you can't. You should use std::string instead. Something similar to what you want can be managed with macros, but shouldn't be done.

How do i convert a QString to a char*

I have a QString that I would like to convert into a char* not a QChar* because I'll be passing it into a method that takes a char*, however I can't convert it without it getting a const char*. For example I have tried:
QString name = "name";
QByteArray byteArray = name.toUtf8();
myMailboxName = byteArray.constData();
and
QString name = "name";
QByteArray byteArray = name.toUtf8();
myMailboxName = byteArray.data();
where myMailboxName is a private char* in my class. However I get an error because it is returning a const char* and can't assign it to a char*. How can I fix this?
This is because data() returns the address of the buffer in the bytearray, you can read it, but obviously you should not write it.
You have your own buffer outside the bytearray. If you want the data, you should copy the buffer of bytearray into the myMailBoName.
use memcpy function
try this code snippet
const char *myMailboxName = name.toLatin1().data();
Use strdup. It does the allocation and the copy at the same time. Just remember to free it once you're done.
You can really use strdup (stackoverflow question about it), as Mike recommends, but also you can do that:
// 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() );
Got there: stackoverflow similar question.
I use something like this wrapper:
template<typename T, typename Y>
void CharPasser(std::function<T(char *)> funcToExecute, const Y& str)
{
char* c = 0;
c = qstrdup(c, str.c_str());
funcToExecute(c);
delete[] c;
}
int SomeFunc(char* ){}
then use it like:
CharPasser<int, std::string>(SomeFunc, QString("test").tostdString())
At least this saves a bit of typing... :)
consider following exampleQString str = "BlahBlah;"try thischar* mychar = strdup(qPrintable(str));or thischar* mychr = str.toStdString().c_str();or thischar* mychar = strdup(str.ascii());Every syntax worked for me ;)

File deletion in c++

I want to delete a file whose path is stored in a std::string object.
I know remove() in <cstdio>, but it takes a const char * as argument.
So is there any direct method to delete the file, like a function which takes the string object as its input?
How about:
string fileName;
//...
remove(fileName.c_str());
Of course, you can always define
int remove(std::string const& fileName)
{
return remove(fileName.c_str());
}
The std::string object will supply you with a const char* representation via the c_str() method:
std::string filename = ...
remove(filename.c_str());
std::string has a method called c_str() that will return a const char * of the std::string. Make use of that!
You could use c_str() method:
std::string somePath( "/lib/" );
remove( somePath.c_str() );