文字列内のすべての部分文字列を置き換える関数をCで作成しようとしています。私は自分の関数を作成しましたが、大きい文字列内の最初の部分文字列でのみ機能します。
これまでのコードは次のとおりです。
void strreplace(char string[], char search[], char replace[]){
char buffer[100];
char*p = string;
while((p=strstr(p, search))){
strncpy(buffer, string, p-string);
buffer[p-string] = '\0'; //EDIT: THIS WAS MISSING
strcat(buffer, replace);
strcat(buffer, p+strlen(search));
strcpy(string, buffer);
p++;
}
}
私はCプログラミングに不慣れではありませんが、ここで何かが足りません。
例:入力文字列「mariehas apples has」の場合、「has」を検索して「blabla」に置き換えます
最初の「has」は正しく置き換えられますが、2番目の「has」は正しく置き換えられません。最終出力は「marie blabla apples hasblabla」です。 2番目の「持っている」がまだそこにあることに注意してください。
私は何が間違っているのですか? :)
EDIT Isは現在動作しています。 null終了文字を追加すると、問題が修正されました。結果の文字列は100より大きくなる可能性があることを知っています。これは学校の宿題なので、20文字以上の文字列は使用しません。
手始めに:
この線
strncpy(buffer, string, p-string);
buffer
にコピーされたものに必ずしも0
ターミネータを追加する必要はありません。
次の行
strcat(buffer, replace);
ただし、buffer
が0
で終了することに依存しています。
buffer
が初期化されておらず、0
ターミネーターが後者の行を見逃している可能性が高いため、buffer
のメモリを超えて読み取られ、悪名高い未定義の振る舞いが呼び出される可能性があります。
あなたがどのアルゴリズムに従おうとしているのか私にはわかりません、それはすべて私には怪しいように見えます。おそらく最も簡単なアプローチは次のとおりです。
p
ポインターをインクリメントして、針の直後を指すようにしますvoid str_replace(char *target, const char *needle, const char *replacement)
{
char buffer[1024] = { 0 };
char *insert_point = &buffer[0];
const char *tmp = target;
size_t needle_len = strlen(needle);
size_t repl_len = strlen(replacement);
while (1) {
const char *p = strstr(tmp, needle);
// walked past last occurrence of needle; copy remaining part
if (p == NULL) {
strcpy(insert_point, tmp);
break;
}
// copy part before needle
memcpy(insert_point, tmp, p - tmp);
insert_point += p - tmp;
// copy replacement string
memcpy(insert_point, replacement, repl_len);
insert_point += repl_len;
// adjust pointers, move on
tmp = p + needle_len;
}
// write altered string back to target
strcpy(target, buffer);
}
警告:関数の呼び出し方法にも注意する必要があります。交換用の文字列が針よりも大きい場合、変更された文字列は元の文字列よりも長くなるため、元のバッファが変更された文字列を含むのに十分な長さであることを確認する必要があります。例えば。:
char s[1024] = "marie has apples has";
str_replace(s, "has", "blabla");
char *replace_str(char *str, char *orig, char *rep)
{
static char buffer[4096];
char *p;
int i=0;
while(str[i]){
if (!(p=strstr(str+i,orig))) return str;
strncpy(buffer+strlen(buffer),str+i,(p-str)-i);
buffer[p-str] = '\0';
strcat(buffer,rep);
printf("STR:%s\n",buffer);
i=(p-str)+strlen(orig);
}
return buffer;
}
int main(void)
{
char str[100],str1[50],str2[50];
printf("Enter a one line string..\n");
gets(str);
printf("Enter the sub string to be replaced..\n");
gets(str1);
printf("Enter the replacing string....\n");
gets(str2);
puts(replace_str(str, str1, str2));
return 0;
}
入力:マリーはリンゴを持っています
出力:マリーブラブラリンゴブラブラ
int replace_str(char* i_str, char* i_orig, char* i_rep)
{
char l_before[2024];
char l_after[2024];
char* l_p;
int l_origLen;
l_origLen = strlen(i_orig);
while (l_p = strstr(i_str, i_orig)) {
sprintf(l_before ,"%.*s" ,l_p - i_str ,i_str);
sprintf(l_after ,"%s" ,l_p + l_origLen);
sprintf(i_str ,"%s%s%s" ,l_before ,i_rep ,l_after);
}
return(strlen(i_str));
}