2011-12-23 12 views
2

http://1.1.1.1/test.mpgのようなリンクがあるとします。次に、それをhttp://1.1.1.1/test.mkvに変更します。どのようにCで "mpg"を "mkv"にプログラム的に変更できますか?私はstrtokとstrcpyを使用しようとしましたが、C言語ではうまくいかないため、できませんでした。const char *をCの別の文字列に置き換えるには?

+0

C言語ではBoostのRegExライブラリを使うことができるので、Cの代わりにC++が使用されています。 –

+0

私はcppを使用しています。しかし、c関数もこれを行うことができます。 – sjor

+0

cppを使用している場合は、絶対にする必要がない限り、 'const char *'を使わないでください。代わりにstd :: stringを使用してください。 – LiKao

答えて

2

以下は解決策ですが、実験のために残したことが1つあります。

mallocメモリがfreeではありません。あなた自身で試してみてください!

もう1つの欠点は、文字列の最初の出現箇所だけを置き換えることです。このコードを改善して、文字列のすべての出現箇所を置き換えます。

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

ありがとうございました。 – sjor

2

const char *からの文字の変更は、コンパイラによって許可されてはならず、明示的キャストによってchar *に変更されると、未定義の動作につながります。

あなたがいずれかのグローバルまたはスタック上に格納された配列として文字列を宣言する場合:

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

次にあなたがconst char *に対処し、文字を変更していないがOKです。それ以外の場合は、

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

文字列リテラルは、おそらく、プロセスの読み取り専用の保護地域と、おそらく保護違反が発生します書き込もうに保存されます。

+0

+1ですが、それは "先行すべき"ではありませんが、未定義の振る舞いにつながります。 –

+0

私がまだやったことを見せてあげましょう:(const char * urlは関数のパラメータです。)int len = strlen(url); const char * last_three =&url [len-3]; char str [512]; char * ptr; strcpy(str、url); strtok_r(str、last_three、&ptr); strは "h"を返します – sjor

2

const char*を変更しないでください。変更すると、の未定義の動作になります。通常、理由のためにconstがあります。

これ以外にも、新しいchar*を作成し、内容をコピーして修正する必要があります。

+0

'const char *'は*必ずしも文字列リテラルではありません...とにかくそれを変更できるわけではありません... – delnan

+0

問題はどのようにわかりません – sjor

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」の長さが同じであるため、この場合には、これが唯一、そうsmoothely動作すること。そうでなければ、もっと複雑なテクニックが必要です。

+0

残念なことに私の場合、最初の長さは16、2番目の長さは4です。 – sjor

+0

次に、より大きなバッファを割り当て、適切な場所に文字列をトークン化し、これらのトークンを新しいバッファに1つずつコピーします。交換する必要があります。 – LiKao

関連する問題