【问题标题】:How to replace a piece of const char* with another string in C?如何用C中的另一个字符串替换一段const char *?
【发布时间】:2011-12-23 12:31:41
【问题描述】:

假设您有一个类似http://1.1.1.1/test.mpg 的链接。然后你想把它改成http://1.1.1.1/test.mkv。如何在 C 中以编程方式将“mpg”更改为“mkv”?我尝试使用 strtok 和 strcpy,但我的 C 语言不好,所以我做不到。

【问题讨论】:

  • 您说的是 C,但其中一个标签是 C++,您使用的是哪个标签,因为使用 C++ 您可以使用 Boost 的 RegEx 库。
  • 我正在使用 cpp。但是一个 c 函数也可以做到这一点。
  • 如果您使用的是 cpp,请不要使用 const char *,除非您必须这样做。请改用 std::string。

标签: c string replace split


【解决方案1】:

以下是解决方案,但还有一件事留给你做实验!

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

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

#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】:

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

    除此之外,您应该创建一个新的char*,复制其中的内容,然后对其进行修改。

    【讨论】:

    • A const char * 不一定是字符串文字。不是说你可以改变它......
    • 问题是我不知道怎么修改。
    【解决方案3】:

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

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

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

    那么你不是在处理const char * 并且改变字符是可以的。否则,

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

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

    【讨论】:

    • +1 但不是“应该导致”,而是“将导致”未定义的行为。
    • 让我告诉你我已经做了什么:(const char *url 是函数的参数。) int len = strlen(url); const char *last_three = &url[len - 3];字符 str[512];字符 *ptr; strcpy(str, url); strtok_r(str, last_three, &ptr);现在 str 只返回“h”
    【解决方案4】:

    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”的长度是相同的。如果不是,您需要一些更复杂的技术。

    【讨论】:

    • 不幸的是,在我的情况下,第一个的长度是 16,第二个的长度是 4。
    • 然后分配一个更大的缓冲区,在适当的地方标记你的字符串,然后将这些标记一一复制到新的缓冲区。复制时替换你需要替换的东西。
    猜你喜欢
    • 2013-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-18
    • 1970-01-01
    • 2021-06-15
    • 2013-12-03
    • 2013-12-23
    相关资源
    最近更新 更多