converting sting to char pointer - c++

I want to convert QString in to char*.
How would I do this?
Thanks.

Use the toAscii/toLatin1/toUtf8 QString methods to get a plain character array (QByteArray). Which method you need depends on the encoding you want the character data to be in. For other encodings see QTextCodec. From a QByteArray, you can get a const char* using QByteArray::constData() or a char* using QByteArray::data(). Use constData() wherever you can, as data() often will create a copy that is unnecessary unless you need to modify the data via the char*.
Also note that const char* data = str.toUtf8().constData() might work, but is dangerous as the temporary QByteArray created in toUtf8() is destroyed right after the end of statement. As the char* returned from constData() becomes invalid when the byte array is destroyed, you should keep the byte array in a temporary variable, like this:
const QByteArray ba = str.toUtf8(); // or toAscii, toLatin1, depending on the encoding you want
const char* data = ba.constData();

char * s = qtString.toStdString().c_str();

Related

String to const char conversion using c_str() or toCharArray()?

I want to know more about programming and after a bit of googling I found how to convert a string to a const char.
String text1;
What I do not understand is why c_str() works,
const char *text2 = text1.c_str();
contrary to toCharArray()?
const char *text2 = text1.toCharArray();
or
const char text2 = text1.toCharArray();
The latter is more logical to me as I want to convert a string to a char, and then turn it into a const char. But that doesn't work because one is a string, the other is a char. The former, as I understand, converts the string to a C-type string and then turns it into a const char. Here, the string suddenly isn't an issue anymore oO
.
a) Why does it need a C-type string conversion and why does it work only then?
b) Why is the pointer needed?
c) Why does a simple toCharArray() not work?
.
Or do I do something terribly wrong?
Thanks heaps.
I am using PlatformIO with Arduino platform.
If you need to modify the returned c-style string in any way, or have it persist after you modify the original String, you should use toCharArray.
If you only need a null-terminated c-style string to pass as a read-only parameter to a function, use c_str.
Arduino reference for String.toCharArray()
Arduino reference for String.c_str()
The interface (and implementation) of toCharArray is shown below, from source
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
{ getBytes((unsigned char *)buf, bufsize, index); }
So your first issue is that you're trying to use it incorrectly. toCharArray will COPY the underlying characters of your String into a buffer that you provide. This must be extra space that you have allocated, either in a buffer on the stack, or in some other writable area of memory. You would do it like this.
String str = "I am a string!";
char buf[5];
str.toCharArray(buf, 5);
// buf is now "I am\0"
// or you can start at a later index, here index 5
str.toCharArray(buf, 5, 5);
// buf is now "a st\0"
// we can also change characters in the buffer
buf[1] = 'X';
// buf is now "aXst\0"
// modifying the original String does not invalidate the buffer
str = "Je suis une chaine!";
// buf is still "aXst\0"
This allows you to copy a string partially, or at a later index, or anything you want. Most importantly, this array you copy into is mutable. We can change it, and since it's a copy, it doesn't affect the original String we copied it from. This flexibility comes with a cost. First, we have to have a large enough buffer, which may not be known at compile time, and takes up memory. Second, that copying takes time to do.
But what if we're calling a function that just wants to read a c-style string as input? It doesn't need to modify it at all?
That's where c_str() comes in. The String object has an underlying c-string type array (yes, null terminator and all). c_str() simply returns a const char* to this array. We make it const so that we don't accidentally change it. An object's underlying data should not be changed by random functions outside of its control.
This is the ENTIRE code for c_str():
const char* c_str() const { return buffer; }
You already know how to use it, but to illustrate a difference:
String str = "I am another string!";
const char* c = str.c_str();
// c[1] = 'X'; // error, cannot modify a const object
// modifying the original string may reallocate the underlying buffer
str = "Je suis une autre chaine!";
// dereferencing c now may point to invalid memory
Since c_str() simply returns the underlying data pointer, it's fast. But we don't want other functions to be allowed to modify this data, so it's const.

convertion from QString to char pointer generates empty string

Here's some test code:
QString qstr_test("TEST");
const char *p = qstr_test.toStdString().c_str();
cout << p << endl;
Nothing is output as p is an empty string.
Here's what I got at debugging:
std::basic_string<char,std::char_traits<char>,std::allocator<char> >::c_str
returns: 0x003bf9d4 "TEST"
p : 0x003bf9d4 ""
It seems p is pointing to the right location but doesn't display the right content.
Why is p empty ?
std::string object is temporary and is destroyed right after c_str() is completed. But std::string owns char* buffer returned by c_str() and this buffer is also destroyed. So your code is incorrect and dangerous. You need to store std::string as long as you use char* buffer:
std::string s = qstr_test.toStdString();
const char* p = s.c_str();
Also it seems pointless to create std::string just to convert it to char*. QString has better methods: toLatin1, toLocal8bit, and toUtf8. Note that returned QByteArray has the same issue that is a common source of mistakes. QByteArray also must be stored if you want to use its buffer.
QByteArray array = qstr_test.toUtf8();
const char* p = array.constData();
I think this method is better because here you specify explicitly the encoding you need to use. And toStdString result depends on QTextCodec::codecForCStrings() current value.

C++ change value in const char

I have a const char
const char example[] = "\x4D\x5A\xE8\x00\x00\x00\x00\x5B\x52\x45\x55\x89\xE5\x81\xC3";
and
DWORD* example2 = "\xAA\xBB\xCC\xDD";
and i want to change the last 4 bytes of example1 with those on example2
what can I do in C++?
i have tried memcpy , strcpy and strcpy_s with no luck
You should not modify a constant array!
Modifying a inherently constant object/variable leads to Undefined Behavior.
Just don't do it. Make a copy of it and modify that copy or if you want to modify the same array simply don't declare it as const.
Donot modify a constant string.
const char example[] = "\x4D\x5A\xE8\x00\x00\x00\x00\x5B\x52\x45\x55\x89\xE5\x81\xC3"; here, your string has a few NULL string terminator. This will NOT work with functions in <string.h> (such as strlen() and others)
Instead use memcpy, memset functions to append ONLY after knowing the length of the binary string.
Store your result in a character array, but don't assume it will work as a regular string because of your data.
your example[] char array is defined as const so you can not modify it.
1) You should get an eror in the compilation if you change your const char array in this way
example[2] ='R';
2) You should get a warning if you modify your const char array via memcpy or via strcpy
Change it to
char example[] = "\x4D\x5A\xE8\x00\x00\x00\x00\x5B\x52\x45\x55\x89\xE5\x81\xC3";
And you can not use strcpy because your character array contains x00 in the middle so this will affect the strcpy function. Because strcpy stop when it find x00 in the char array
example[] char array contains x00 in the middle, so to find the length of example[] with strlen will not work properly. For this case I suggest to use sizeof(example) instead.
Here after how you can make your copy:
char example[] = "\x4D\x5A\xE8\x00\x00\x00\x00\x5B\x52\x45\x55\x89\xE5\x81\xC3";
DWORD* example2 = "\xAA\xBB\xCC\xDD";
if (sizeof(example)>=sizeof(example2))
memcpy(example+sizeof(example)-sizeof(example2), example2, sizeof(example2));
Const variables can't be changed. This is by design. In the case of a c string, you can have the contents of the string const or the pointer to the string const.
Since you are defining it as a const character array, the pointer is implicitely const and the contents are explicitly const.
const char * const mystring = "hello"
In this case the first "const" tries to apply left (there is nothing), so it applies right (to the char type). So the string content may not change. The second const tries to apply left, so it makes the pointer itself const. That means that the mystring pointer must always point to where the "h" from "hello" in memory is.
So afterwards if I try:
mystring[0] = "y"
or
mystring = "gooodbye!"
They would not work. If you removed the first or second const respectively, they could be made to work.
The purpose of const allows you to say ahead of time "this variable cannot be modified". That means that if it is modified then there is a problem. Generally you should always use const with any variable that you do not want to be modified after instantiation.
You should never modify a constant including a constant array. If you want to change what you have above, create a copy of it and change the copy. As pointed out by RasmusKaj strcpy will not help you here as the source strings contains zero chars so maybe use memcpy for the creation of the copy.

Convert std::string to char * alternative

I have done a search in google and been told this is impossible as I can only get a static char * from a string, so I am looking for an alternative.
Here is the situation:
I have a .txt file that contains a list of other .txt files and some numbers, this is done so the program can be added to without recompilation. I use an ifstream to read the filenames into a string.
The function that they are required for is expecting a char * not a string and apparently this conversion is impossible.
I have access to this function but it calls another function with the char * so I think im stuck using a char *.
Does anyone know of a work around or another way of doing this?
In C++, I’d always do the following if a non-const char* is needed:
std::vector<char> buffer(str.length() + 1, '\0');
std::copy(str.begin(), str.end(), buffer.begin());
char* cstr = &buffer[0];
The first line creates a modifiable copy of our string that is guaranteed to reside in a contiguous memory block. The second line gets a pointer to the beginning of this buffer. Notice that the vector is one element bigger than the string to accomodate a null termination.
You can get a const char* to the string using c_str:
std::string str = "foo bar" ;
const char *ptr = str.c_str() ;
If you need just a char* you have to make a copy, e.g. doing:
char *cpy = new char[str.size()+1] ;
strcpy(cpy, str.c_str());
As previous posters have mentioned if the called function does in fact modify the string then you will need to copy it. However for future reference if you are simply dealing with an old c-style function that takes a char* but doesn't actually modfiy the argument, you can const-cast the result of the c_str() call.
void oldFn(char *c) { // doesn't modify c }
std::string tStr("asdf");
oldFn(const_cast< char* >(tStr.c_str());
There is c_str(); if you need a C compatible version of a std::string. See http://www.cppreference.com/wiki/string/basic_string/c_str
It's not static though but const. If your other function requires char* (without const) you can either cast away the constness (WARNING! Make sure the function doesn't modify the string) or create a local copy as codebolt suggested. Don't forget to delete the copy afterwards!
Can't you just pass the string as such to your function that takes a char*:
func(&string[0]);

How do I convert a string to a char* in c++?

I have an error in my program: "could not convert from string to char*". How do I perform this conversion?
If you can settle for a const char*, you just need to call the c_str() method on it:
const char *mycharp = mystring.c_str();
If you really need a modifiable char*, you will need to make a copy of the string's buffer. A vector is an ideal way of handling this for you:
std::vector<char> v(mystring.length() + 1);
std::strcpy(&v[0], mystring.c_str());
char* pc = &v[0];
Invoke str.c_str() to get a const char*:
const char *pch = str.c_str();
Note that the resulting const char* is only valid until str is changed or destroyed.
However, if you really need a non-const, you probably shouldn't use std::string, as it wasn't designed to allow changing its underlying data behind its back. That said, you can get a pointer to its data by invoking &str[0] or &*str.begin().
The ugliness of this should be considered a feature. In C++98, std::string isn't even required to store its data in a contiguous chunk of memory, so this might explode into your face. I think has changed, but I cannot even remember whether this was for C++03 or the upcoming next version of the standard, C++1x.
If you need to do this, consider using a std::vector<char> instead. You can access its data the same way: &v[0] or &*v.begin().
//assume you have an std::string, str.
char* cstr = new char[str.length() +1];
strcpy(cstr, str.c_str());
//eventually, remember to delete cstr
delete[] cstr;
Use the c_str() method on a string object to get a const char* pointer. Warning: The returned pointer is no longer valid if the string object is modified or destroyed.
Since you wanted to go from a string to a char* (ie, not a const char*) you can do this BUT BEWARE: there be dragons here:
string foo = "foo";
char* foo_c = &foo[0];
If you try to modify the contents of the string, you're well and truly on your own.
If const char* is good for you then use this: myString.c_str()
If you really need char* and know for sure that char* WILL NOT CHANGE then you can use this: const_cast<char*>(myString.c_str())
If char* may change then you need to copy the string into something else and use that instead. That something else may be std::vector, or new char[], it depends on your needs.
std::string::c_str() returns a c-string with the same contents as the string object.
std::string str("Hello");
const char* cstr = str.c_str();