I know how to change a char in a char array but I wonder if we can change one element of a C-string pointed by a char pointer?
Code:int main()
{
char * p = "Hello World";
*(p+1) = 'x';
cout << p << endl;
return 0;
}
Printable View
I know how to change a char in a char array but I wonder if we can change one element of a C-string pointed by a char pointer?
Code:int main()
{
char * p = "Hello World";
*(p+1) = 'x';
cout << p << endl;
return 0;
}
Well, I feel a bit strange to see a guy with 643 posts not using class string in C++.
You handle strings the C way. And of course, no. You can use some flag in the compilation procedure to allow this to happen.
Why? Because this is a string literal! String literals can not modify their data, but they can modify their pointer.
On the other hand, if you had an array, then the opposite stands true. You can not modify the pointer, but you can modify the data :)
Yes, but that code will probably result in a segment violation - in this case, `p' should realy be `const char *' since initializing it like this may place the string in read-only memory. Initializing it as an array will place it on the stack where it can be treated as a `char *'.
In short, change your definition of `p' to:
Code:char p[] = "Hello World";
Example with string literal.
OutputCode:#include <stdio.h>
int main(void)
{
char* strLiteral = "I am a string literal!";
char* origin = strLiteral;
printf("I am about to chrash...!\n");
*(strLiteral+1) = 'W';
printf("Did I?\n");
printf("%s\n", origin);
return 0;
}
While with the arrayCode:linux05:/home/users/std10093>px
I am about to chrash...!
Segmentation fault
On linux I got output:Code:#include <stdio.h>
int main(void)
{
char str[15] = "a string";
printf("I can modify the data...\n");
*(str+1) = 'W';
printf("But not the pointer...!\n");
str++;
printf("%s\n", str);
return 0;
}
and on windowsCode:linux05:/home/users/std10093>gcc -Wall px.c -o px
px.c: In function 'main':
px.c:11: error: lvalue required as increment operand
Hope that helps!Code:main.c: In function `main':
main.c:11: error: wrong type argument to increment
make[2]: *** [build/Debug/Cygwin-Windows/main.o] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
Thank you, that helped.
So why are you using C strings, now?
Maybe he uses the string class, but wanted to remember how it feels handling strings in C way :P
Let's not assume things... though, when these things show up, I get kind of worried that Ducky is trying to climb up the wrong path again...
I'd prefer to say that a pointer can change its string literal. I wouldn't really say that, it sounds awkward, but the point is that string literal should be pointed to, it doesn't own it's own pointer and the data itself doesn't really decay into a pointer. A string literal is actually "This" or "this" -- objects of type char[5] -- the data proper.
char *p = "This";
p can be reassigned, because it is a pointer. And that very syntax is only allowed as a convenience. A convenience which C++ copied from the beginning, I think, but nonetheless. Before C was standardized, you needed to do magic like this:
char * p;
char cs[] = "This";
p = cs;
I will even link a FAQ answer later that shows the difference between a pointer pointing to an array object and an array itself with pictures.
This code that you posted is actually guaranteed not to work.
Arrays cannot be reassigned, because that's illegal. If arrays were pointers, then it would be legal. str++; is:
str = str + 1;
which means that this requires array assignment. With a pointer, this operation is fine, though it's not guaranteed to point to a dereferenceable location. In other words, you can do this:
But you cannot increment foo here, because foo is an array type. Try, and you will get that error. foo is the wrong type to increment.Code:#include <stdio.h>
#include <ctype.h>
int main(void) {
char foo[] = "My sample string.";
for (char *bar = foo; *bar != '\0'; bar++) {
*bar = toupper(*bar);
}
printf("%s\n", foo);
return 0;
}
Try reading this FAQ answer.
lol
@Elysia
I was looking at somebody's code and I was wondering why was that working when 'pa' is declared as a pointer so the value it was pointing couldn't be changed.
Is it because of VirtualProtect()?
Code:DWORD_PTR pa = 0x12340011;
BYTE *p = (BYTE *)pa;
VirtualProtect((void *)pa,5,
PAGE_EXECUTE_READWRITE,&OldProtect);
p[0] = (BYTE)0xE9;
for (int i = 0; i < 4; i++)
p[i + 1] = p2[i];
It's because it is of type void, so you can't have an array of type void, but a pointer to void! :)
Elysia, I told that in terms of fun mostly, don't get so upset :)
The more you know something, the easier you can explain. I believe that you have a good knowledge, so rephrase what you said.
Ι believe I said that too.
That is what I am trying to say... but thanks for the FAQ, since I didn't know about this page.
Exactly! The code I posted was for demonstration of which you can do and what you can't! I thought this was clear by the printfs ;)
However, I like your example, so I am going to augment my upload on my page with your example and the faq link. Of course you will get the credits ;)
EDIT: Here it is.
I hope you are doing this because you didn't understand me somehow.
String literals have a type. It's array of char. And while you said "String literals can not modify their data, but they can modify their pointer," my main problem with this is that they don't have a pointer like you implied. The pointer and the string literal are actually separate things.
Please. I give 0 ........s about credit here.Quote:
Ι believe I said that too.
That is what I am trying to say... but thanks for the FAQ, since I didn't know about this page.
Exactly! The code I posted was for demonstration of which you can do and what you can't! I thought this was clear by the printfs ;)
However, I like your example, so I am going to augment my upload on my page with your example and the faq link. Of course you will get the credits ;)
If you were trying to say what I said, I felt I needed to rephrase your post anyway. You kept referring to arrays as pointers. Arrays are not pointers. And I thought it was important enough to say that arrays in general can't be reassigned, and it's not just a string literal issue.