如何用C中的另一个字符串替换一段const char *?

时间:2011-12-23 12:31:41

标签: c string replace split

假设您有http://1.1.1.1/test.mpg之类的链接。然后您想将其更改为http://1.1.1.1/test.mkv。如何在C中以编程方式将“mpg”更改为“mkv”?我尝试使用strtok和strcpy,但我不擅长C,所以我做不到。

4 个答案:

答案 0 :(得分:2)

编译器不允许更改const char *中的字符,如果通过显式强制转换为char *,则会导致未定义的行为。

如果将字符串声明为全局或堆栈存储的数组:

char str[] = "http://1.1.1.1/test.mpg";

然后你没有处理const char *并且改变字符是可以的。否则,

char *str = "http://1.1.1.1/test.mpg";

字符串文字可能存储在进程的只读受保护区域中,并且尝试在那里写入很可能会产生保护错误。

答案 1 :(得分:2)

您不应该更改const char*。更改它将导致未定义的行为。通常,const是有原因的。

除此之外,您应该创建一个新的char*,复制其中的内容,并修改它。

答案 2 :(得分:2)

以下是解决方案,但您还有一件事需要进行试验!

以下代码中的malloc'内存不是free。自己试试吧!

另一个缺点是,它确实只替换了第一次出现的字符串..所以你cna改进这段代码来替换所有出现的字符串!

#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
$ 

答案 3 :(得分:1)

不能也不能更改const char *指针。这由const表示,显然告诉该指针指向常量字符。

如果您需要以编程方式更改此变量中的某些内容,则唯一的选择是首先将其复制到另一个足够大小的变量并进行更改。为此,您可以使用数组索引更改最后几个字节。这样的事情会起作用:

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';

请注意,在这种情况下,这只能顺利运行,因为“mkv”和“mpg”的长度是相同的。如果不是,你需要一些更复杂的技术。