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.
Related
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.
So I have a string which contains "RGGB" and I need it to be in a char array to perform some operations. Then I need to replace certain characters for a blank space, for example the first 'G', so that my char array remains "R GB".
How can I do this? So far I tried this solution:
int main()
{
string problem="RGGB";
const char *p=problem.c_str();
p[1]=' ';
return p;
}
I get the error:
assignment of read only location *(p + ((sizetype)i))
To access the "interal string" (I mean a const char*) of a std::string, there are two member functions provided: std::string::c_str and std::string::data. Until C++11, the difference was that std::string::data wasn't bound to return a pointer to a null-terminated const char* while std::string::c_str was. Now, they are equivalent. And both return a const char*, even before C++11.
There are several approaches to your problem:
Use std::strdup or std::str(n)cpy to duplicate the string and write to the duplicate.
Use a const_cast. Pretty drastic, but, if it doesn't hurt any rules (FYI, it does), works.
Don't use std::string at all. Do what you want with a char* and then optionally convert it to a std::string later.
Just use the functionality of std::string.
string, a C++ class, does not provide directly alterable access to its innerds via a char *. While you could cast away the const, this is dangerous because compilers may use the const as an optimization path.
If you absolutely need to do this just use a char array, not a string or alter the contents of the string using string methods.
p[1]=' ';
is not valid as const char * is read-only pointer.
in other words, it is a const pointer.
remember:
When const appears to the left of the *, what's pointed to is constant, and if const appears to the right of the *, the pointer itself is constant. If const appears on both sizes, both are constants.
this code might work:
char problem[]="RGGB";
char* p = problem;
p[1]=' ';
cout<<problem;
The answer is in your question:
I need it to be in a char array
Then put it in a char array:
char problem[] = "RGGB";
problem[1] = ' ';
Problem solved.
If, on the other hand, you want to solve the problem using actual C++:
std::string problem = "RGGB";
problem.at(1) = ' ';
I'm new in c++ language and I am trying to understand the pointers concept.
I have a basic question regarding the char pointer,
What I know is that the pointer is a variable that stores an address value,
so when I write sth like this:
char * ptr = "hello";
From my basic knowledge, I think that after = there should be an address to be assigned to the pointer, but here we assign "hello" which is set of chars.
So what does that mean ?
Is the pointer ptr points to an address that stores "hello"? or does it store the hello itself?
Im so confused, hope you guys can help me..
Thanks in advance.
ptr holds the address to where the literal "hello" is stored at. In this case, it points to a string literal. It's an immutable array of characters located in static (most commonly read-only) memory.
You can make ptr point to something else by re-assigning it, but before you do, modifying the contents is illegal. (its type is actually const char*, the conversion to char* is deprecated (and even illegal in C++11) for C compatibility.
Because of this guarantee, the compiler is free to optimize for space, so
char * ptr = "hello";
char * ptr1 = "hello";
might yield two equal pointers. (i.e. ptr == ptr1)
The pointer is pointing to the address where "hello" is stored. More precisely it is pointing the 'h' in the "hello".
"hello" is a string literal: a static array of characters. Like all arrays, it can be converted to a pointer to its first element, if it's used in a context that requires a pointer.
However, the array is constant, so assigning it to char* (rather than const char*) is a very bad idea. You'll get undefined behaviour (typically an access violation) if you try to use that pointer to modify the string.
The compiler will "find somewhere" that it can put the string "hello", and the ptr will have the address of that "somewhere".
When you create a new char* by assigning it a string literal, what happens is char* gets assigned the address of the literal. So the actual value of char* might be 0x87F2F1A6 (some hex-address value). The char* points to the start (in this case the first char) of the string. In C and C++, all strings are terminated with a /0, this is how the system knows it has reached the end of the String.
char* text = "Hello!" can be thought of as the following:
At program start, you create an array of chars, 7 in length:
{'H','e','l','l','o','!','\0'}. The last one is the null character and shows that there aren't any more characters after it. [It's more efficient than keeping a count associated with the string... A count would take up perhaps 4 bytes for a 32-bit integer, while the null character is just a single byte, or two bytes if you're using Unicode strings. Plus it's less confusing to have a single array ending in the null character than to have to manage an array of characters and a counting variable at the same time.]
The difference between creating an array and making a string constant is that an array is editable and a string constant (or 'string literal') is not. Trying to set a value in a string literal causes problems: they are read-only.
Then, whenever you call the statement char* text = "Hello!", you take the address of that initial array and stick it into the variable text. Note that if you have something like this...
char* text1 = "Hello!";
char* text2 = "Hello!";
char* text3 = "Hello!";
...then it's quite possible that you're creating three separate arrays of {'H','e','l','l','o','!','\0'}, so it would be more efficient to do this...
char* _text = "Hello!";
char* text1 = _text;
char* text2 = _text;
char* text3 = _text;
Most compilers are smart enough to only initialize one string constant automatically, but some will only do that if you manually turn on certain optimization features.
Another note: from my experience, using delete [] on a pointer to a string literal doesn't cause issues, but it's unnecessary since as far as I know it doesn't actually delete it.
char el[3] = myvector[1].c_str();
myvector[i] is a string with three letters in. Why does this error?
It returns type char* which is a pointer to a string. You can't assign this directly to an array like that, as that array already has memory assigned to it. Try:
const char* el = myvector[1].c_str();
But very careful if the string itself is destroyed or changed as the pointer will no longer be valid.
Because a const char * is not a valid initializer for an array. What's more, I believe c_str returns a pointer to internal memory so it's not safe to store.
You probably want to copy the value in some way (memcpy or std::copy or something else).
In addition to what others have said, keep in mind that a string with a length of three characters requires four bytes when converted to a c_str. This is because an extra byte has to be reserved for the null at the end of the string.
Arrays in C++ must know their size, and be provided with initialisers, at compile-time. The value returned by c_str() is only known at run-time. If e1 were a std::string, as it probably should be, there would be no problem. If it must be a char[], then use strcpy to populate it.
char el[3];
strcpy( e1, myvector[1].c_str() );
This assumes that the string myvector[1] contains at most two characters.
Just create a copy of the string. Then, if you ever need to access it as a char*, just do so.
string el = myvector[1];
cout << &el[0] << endl;
Make the string const if you don't need to modify it. Use c_str() on 'el' instead if you want.
Or, just access it right from the vector with:
cout << &myvector[1][0] << endl;
if possible for your situation.
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]);