Assume that you have a link like http://1.1.1.1/test.mpg
. Then you want to change it to http://1.1.1.1/test.mkv
. How can you change "mpg" to "mkv" programmatically in C? I tried to use strtok and strcpy but I am not good in C so I couldn't do it.
问题:
回答1:
The following is the solution, but there is one thing left to you for experimenting!
The malloc
'ed memory is not free
'd in the below code. Try it on your own!
One other drawback is, it does replace only the first occurrence of the string.. So you cna improve this code to replace all the occurrence of the string!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * strrep(char *str, char *o_s, char *n_s)
{
char *newstr = NULL;
char *c = NULL;
/* no substring found */
if ((c = strstr(str, o_s)) == NULL) {
return str;
}
if ((newstr = (char *) malloc((int) sizeof(str) -
(int) sizeof(o_s) +
(int) sizeof(n_s) + 1)) == NULL) {
printf("ERROR: unable to allocate memory\n");
return NULL;
}
strncpy(newstr, str, c-str);
sprintf(newstr+(c-str), "%s%s", n_s, c+strlen(o_s));
return newstr;
}
int main(void)
{
char str[] = "http://1.1.1.1/test.mpg";
char old_s[] = "mpg";
char new_s[] = "mkv";
char *str_new = strrep(str, old_s, new_s);
if (str_new != NULL) {
printf("Original : %s\n", str);
printf("Replaced : %s\n", str_new);
}
return 0;
}
$ gcc strrep.c
$ ./a.out
Original : http://1.1.1.1/test.mpg
Replaced : http://1.1.1.1/test.mkv
$
回答2:
You shouldn't change a const char*
. Changing it will lead to undefined behavior. Usually, a const
is there for a reason.
That aside, you should create a new char*
, copy the contents inside it, and modify that.
回答3:
Changing a character from a const char *
should not be allowed by the compiler, and if done via an explicit cast to char *
will lead to undefined behaviour.
If you declare the string as an array that is stored either globally or on the stack:
char str[] = "http://1.1.1.1/test.mpg";
Then you are not dealing with const char *
and altering characters is OK. Otherwise,
char *str = "http://1.1.1.1/test.mpg";
the string literal will possibly be stored in a read-only protected area of the process and an attempt to write there will most probably generate a protection fault.
回答4:
A const char *
pointer cannot and must not be changed. This is indicated by the const
, that obviously tells that this pointer points to constant characters.
If you need to change something in this variable programatically your only choice is to first copy it to another variable of sufficient size and change that. For this you can just change the last few bytes by using array indexing. Something like this will work:
const char * url = "http://1.1.1.1/test.mpg";
char * url2;
url2 = malloc( strlen( url ) + 1 );
strcpy( url2, url ); // no need to use strncpy
url2[ strlen( url2 ) - 3 ] = 'm';
url2[ strlen( url2 ) - 2 ] = 'k';
url2[ strlen( url2 ) - 1 ] = 'v';
Note that in this case this only works so smoothely, because the length of "mkv" and "mpg" is the same. If it is not you need some more complicated techiques.