1

特定のディレクトリで .txt ファイルを開くプログラムを作成しています。問題のディレクトリ内のファイルのすべての絶対パスを含む配列があり、ファイルの名前を抽出して返す関数を作成しています。関数は次のように記述されます。

char *name(char *string) {
    int i = strlen(string);
    char *aux;
    while(string[i-1] != '/'){
        i--;
    }
    strcpy(aux, &string[i]); 
    return aux;
}

上記の関数はセグメンテーション違反エラーを出していますが、次の行を追加すると "int j = 0;" になります。aux の宣言の前に間違いがなくなり、新しい作業コードは

char *name(char *string) {
    int i = strlen(string);
    int j = 0;
    char *aux;
    while(string[i-1] != '/'){
        i--;
    }
    strcpy(aux, &string[i]); 
    return aux;
}

入力: C:\test\a.txt
出力: a.txt

「int j = 0;」を追加する理由 問題を解決しますか?この矛盾が後で大きな問題につながるかどうかわからないので、私はそれで立ち往生して続行できません。文字列をコピーする独自の関数を作成することを考えていますが、その前にそれを本当に理解したいですエラー。

4

3 に答える 3

4

を割り当てることはありませんauxaux何かをコピーしようとする前に、有効なメモリ位置を指す必要があります。

の代わりにchar *aux、 のようなものが必要ですchar *aux = malloc(i+1);。あなたの場合、常に少なくとも3文字短くなる(含まれない)i+1ため、やり過ぎであることに注意してください。ただし、おそらくそのような小さな文字列は気にしません。使い終わったら、ポインターを覚えておいてください。auxstringC:\free()

また、宣言の順序を切り替えたり、宣言を追加したりすることで機能することがわかった理由は、おそらく幸運であり、auxポイント先の場所が有効であるためです (単にchar *aux;,を行うauxと、ランダムな場所をポイントします)。ただし、これはまったくの運であり、機能しているように見えても無効なコードです。

将来的には、 Valgrindなどのツールを使用して、メモリの問題を診断することをお勧めします。C での基本的なメモリ管理とポインタに関するチュートリアルも読む必要があります。

于 2012-07-01T04:05:59.537 に答える
3

文字列のファイル名部分をパラメーターとして利用することにのみ関心があるように聞こえるので、別のオプションは、既に持っている文字列の部分を使用することです。

試してみてください: aux = &string[i]; strcpy の代わりに。

これにより、関心のある文字列の部分 (つまり、最後の '/' の後の最後の部分) へのポインターが得られます。

次に、すべての入力文字列に「/」が含まれていることを確認してください。そうしないと、悪いことが起こります (つまり、ループが文字列の先頭を通り過ぎて、ある時点でセグメンテーション違反が発生する可能性があります)。i = 1 を超えてループが継続しないように、ループに条件を付けるのが最善です。

于 2012-07-01T04:22:54.560 に答える
1

にメモリを割り当てませんaux。初期化されていないポインタを介してメモリに書き込もうとしています。

于 2012-07-01T04:08:10.213 に答える