0

I want to do something simple but I've been banging my head on this for too long. I have a string that will always end with a specific "token". In the case below "++". I want to replace the ending token with a shorter token, let's say "#".

strstr returns either NULL or a pointer to the initial ending token. strcpy should take the pointer returned from strstr and overwrite the "++" with "#\0".

At least that's what I think it should do. Instead, I get an "assignment makes integer from pointer without a cast" warning. I have tried strcpy(*newThing, "#"); and a few other things at this point. the things that don't give errors cause seg-faults.

Is it that in this case C is taking the storage for the original string from some immutable space on the stack? Do I need to use one of the "alloc"s? I've tried that too but might have missed something.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    char *thing="ssssssssssssssss++";
    char *newThing;

    newThing = strstr(thing, "++");
    strcpy(newThing, "#");
    printf("%s\n", thing);

    exit(0);
}
M.M
  • 138,810
  • 21
  • 208
  • 365
7 Reeds
  • 2,419
  • 3
  • 32
  • 64
  • 4
    You can't modify a string literal in C(Not even an array in the way you try to modify to "replace" parts of it). – P.P Oct 31 '14 at 22:21
  • Use `strdup` to replace the string literal with a heap allocated copy, or define `thing` as a `char thing[]` to have it allocated on the stack. Also, you should check if `newThing` is `NULL` instead of passing it to `strcpy` unchecked. – Phillip Oct 31 '14 at 22:25
  • 4
    If I replace `char *thing="ssssssssssssssss++";` by `char thing[]="ssssssssssssssss++";`, everything works fine. http://ideone.com/IOPCAI – R Sahu Oct 31 '14 at 22:25

2 Answers2

2

The problem is that thing is a string literal. You could use this:

char thing[]="ssssssssssssssss++";

which will allocate as mush space needed (the complier will automatically figure out the size of the array).

I googled the reason the string literal will fail. I found an example of mine that I had forgotten of. Here it is.

It pretty much boils down to this:

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.

An interesting comment on this was: “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.”

Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
2

Your problem is that thing is a pointer that points to a string literal. In the old days, you could have done that, but current compilers stores string literal in non writeable memory.

So when you execute you code you get a Access violation writing location (or equivalent message).

Simplest way to fix that : declare an automatic array initialized with the string literal, and all is fine :

char thing[]="ssssssssssssssss++";

(an array and a pointer are not exactly the same ...)

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252