How do i convert a QString to a char* - c++

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

Related

String type alternative in C

I currently have a function defined in a header that looks like this
void foo::GetValue(std::string& str);
This function basically assigns a value to str. I need to come up with an alternative to str (basically, nothing that employs the standard library).
The implementation of the above function is like this in the .cpp file:
void foo::GetValue(std::string& str)
{
std::string s = bar.someMethod();
str = s;
}
I want to know what is the best/easiest option for replacing the header?
One approach I had was to replace std::string in the header file with char* so I would have this in the header:
void foo::GetValue(char* str);
And in the implementation I would have this:
void foo::GetValue(char* str)
{
std::string resp = bar.someMethod();
char* c = new char[resp.size() + 1];
std::copy(resp.begin(), resp.end(), c);
c[resp.size()] = '\0';
}
The problem with the above approach is that a lot of files are calling this function and they will need to modify their code. Also, they will need to free the above memory. Two concerns I have with this is that other callers to this function will need to do the following two things
Replace std::string being passed to the function with char*.
Free the char* when done using it.
These two items seem very costly to me to trust other callers to do.
Any suggestions on what I can do to solve this problem? Perhaps change the signature to something else? I would prefer if the caller still passes a string, however string.c_str() is a constant char pointer.
For a given C++ function like this:
std::string foo::GetValue(std::string& str)
{
return bar.someMethod(str);
}
Then your equivalent C code looks like this:
void foo_GetValue(char* str, char* res, size_t size)
{
std::string str_arg = str;
std::string result = bar.someMethod(str_arg);
strncpy(res, result.c_str(), size - 1);
res[size-1] = 0; // Ensure is NUL terminated
}
When calling from C:
void example() {
const BUFFER_LEN = 1024;
char buffer[BUFFER_LEN];
foo_GetValue("example", buffer, BUFFER_LEN);
}

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.

Create String object from std::string by overloading = operator

I've tried several options but my compiler does not pick up the operator overloading or something else is wrong. I'm using XCode 4.5.2 with default Apple LLVM compiler 4.1.
The error I get is this: Assigning to 'cocos2d::CCString *' from incompatible type 'const char [5]'
on these lines:
CCString *s_piece__locks = "TEST";
cocos2d::CCString *s_piece__locks2 = "TEST";
My .h code:
CCString& operator= (const std::string& str);
// CCString& operator= (const char* str); // this doesn't work either
const CCString& operator = (const char *);
My .cpp code (even though this is irelevant):
CCString& CCString::operator= (const std::string& str)
{
m_sString = CCString::create(str)->m_sString;
return *this;
}
const CCString& CCString :: operator = (const char* str)
{
m_sString = CCString::create(str)->m_sString;
return *this;
}
Your help is very appreciated, thanks!
The error message Assigning to 'cocos2d::CCString *' from incompatible type 'const char [5]' suggests that you are assigning a char array to a pointer to cocos2d::CCString.
This should work:
char bar[] = "ABCD";
cocos2d::CCString foo;
foo = bar;
CCString *s_piece__locks = "TEST";
cocos2d::CCString *s_piece__locks2 = "TEST";
What the heck is this supposed to do? Declaring a pointer does not generate any object except the pointer itself. So basically, for this to "work", there would need to be another CCString object around already, that happens to represent the string "TEST". But even if that's given, how is C++ supposed to know which one to point to? It would need to look "TEST" up in some kind of e.g. hash map.
None of this makes any sense. Change your code to either
Direct use of object on stack:
cocos2d::CCString s_piece;
s_piece = "TEST";
Assigning new content to an object that resides somewhere else. You'd normally use a reference for this, e.g.
void assign_test_to(cocos2d::CCString& target) {
target = "TEST";
}
it's also possible with a pointer
void assign_test_to_ptr(cocos2d::CCString* target) {
*target = "TEST";
}
but don't do that unless you have a specific reason to.
In principle, there's another possibility:
cocos2d::CCString* s_piece_locks = new CCString;
*s_piece_locks = "TEST";
but you want to avoid this, as it can very easily lead to memory leaks. What would be ok is
std::unique_ptr<cocos2d::CCString> s_piece_locks = new CCString;
*s_piece_locks = "TEST";

QString to char* conversion

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