Как заменить кусок const char * другой строкой в ​​C? - PullRequest
2 голосов
/ 23 декабря 2011

Предположим, что у вас есть ссылка типа http://1.1.1.1/test.mpg. Затем вы хотите изменить его на http://1.1.1.1/test.mkv. Как вы можете программно изменить «mpg» на «mkv» в C? Я пытался использовать strtok и strcpy, но я не очень хорош в C, поэтому я не смог этого сделать.

Ответы [ 4 ]

2 голосов
/ 23 декабря 2011

Ниже приведено решение, но для экспериментов остается одна вещь!

Память malloc 'не соответствует 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 голосов
/ 23 декабря 2011

Вы не должны менять const char*. Его изменение приведет к неопределенному поведению . Обычно const существует по причине.

Кроме того, вы должны создать новый char*, скопировать содержимое внутри него и изменить его.

2 голосов
/ 23 декабря 2011

Изменение символа с const char * не должно быть разрешено компилятором, и если это сделано с помощью явного приведения к char *, это приведет к неопределенному поведению.

Если вы объявите строку как массивэто хранится либо глобально, либо в стеке:

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

Тогда вы не имеете дело с const char * и с изменением символов все в порядке.В противном случае

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

строковый литерал, возможно, будет храниться в защищенной области процесса, доступной только для чтения, и попытка записи в него, скорее всего, приведет к ошибке защиты.

1 голос
/ 23 декабря 2011
Указатель

A 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" одинакова. Если это не так, вам нужны более сложные приемы.

...