4

str1テキスト内のすべての出現箇所をで置き換える関数を作成しようとしましtたが、 「バッファオーバーフロー」エラーメッセージが表示されstr2続けます。私の機能の何が問題になっているのか教えていただけますか?

#include <stdio.h>
#include <string.h>
#include <assert.h>

//replace all *str1 in *t with *str2, put the result in *x, return *x
char * result(char *str1,char *str2,char *t)
{
    char *x=NULL,*p=t,*r=t;
    x=malloc(400*sizeof(char));
    assert(x!=NULL);
    x[0]='\0';
    r=strstr(t,str1); //r is at the first occurrence of str1 in t, p is at the beginning of t
    while(r!=NULL)
    {
        strncat(x,p,r-p); //copy r-p chars from p to x
        strcat(x,str2); //copy str2 to x
        p=r+strlen(str1); //p will be at the first char after the last occurrence of str1 in t
        r=strstr(r+strlen(str1),str1); //r goes to the next occurrence of str1 in t
    }
    strcat(x,p);
    return x;
}

この関数を使用して配列gets()を読み取ることはしませんでした。char

私のコンパイラはgccバージョン4.6.3です


コードを更新しましたが、機能しますが、期待どおりの結果が得られません。

main()働き:

int main(void)
{
    char *sir="ab",*sir2="xyz",*text="cabwnab4jkab",*final;
    final=result(sir,sir2,text);
    puts(final);
    free(final);
    return 0;
}

印刷された文字列:

b

期待していたcxyzwnxyz4jkxyz

4

2 に答える 2

7

引数が混同されているようですstrncpy。2番目の引数はソース文字列であり、コピーする文字数の制限ではありません。これは3番目の引数である必要があります。

 strncpy(x, p, r - p); // copy r - p chars from p to x

strcatさらに、の代わりに使用したいstrcpy。を使用strcpyすると、結果の内容が毎回置換文字列で上書きされます。を使用して、開始する前strcatに必ず結果をで初期化してください。\0

最後に、x関数からローカル変数への参照を返します。関数が戻った後はメモリが使用できないため、これを行うことはできません。

于 2012-08-20T22:28:34.390 に答える
2

あなたのコードにはかなりの数の奇妙なバグが含まれています。

まず、x宛先バッファへのポインタです。理由により、すべてのコピーを直接に実行します。xつまり、すべてがバッファの先頭にコピーされ、以前にコピーされたデータが上書きされます。これはまったく意味がありません。なんでこんなことするの?x現在の宛先位置を保持し、その位置にデータを書き込むための専用ポインターを作成する必要があります(に書き込むのではなくx)。

コードを編集し、コピーを連結に置き換えたようです。ええと...問題は解決するかもしれませんが、これはまだ悪い設計です。strcat/strncat関数は良いCコードにはありません。strcatとにかく、初期化されていないバッファで関数を使用しようとしているため、コードはまだ壊れていますxx最初に空の文字列として初期化する必要があります。

第二に、置換文字列の検索には、より微妙な問題があります。サイクルの終わりに、次のシンボルから検索を続行しますr=strstr(r+1,str1)。つまり、検索位置を1だけインクリメントします。これが目的かどうかはわかりません。

入力テキスト aaaa、およびに置き換える要求と見なしaaますbc。この場合、何回交換しますか?何回ありaaますaaaaか?2または3?結果(2回の置換)を取得したい場合は、1ではなく、をbcbc増やす必要があります。rstrlen(str1)

実際、現在の実装では設定しますp=r+strlen(str1)が、位置から検索を続行しますr+1。これにより、私の例のように、検索文字列の出現が重複して完全に無意味な結果になります。これを試して

char *str1="aa",*str2="xyz",*text="aaaa",*final;
final=result(str1,str2,text);

何が起こるか見てみましょう。

于 2012-08-20T22:51:23.170 に答える