3

私は初心者です,tracks.c:

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

char tracks[][5] = {
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
};

void track_search(char search_for[]) {

    int i;
    puts(search_for);
    puts(strstr(tracks[0], search_for));

    /*
    for (i = 0; i < 6; i++) {
        if (strstr(tracks[i], search_for)) {
            printf("tracks %i: %s\n", i,tracks[i]);
        } else {
            puts("Nothing found");
        }
    }
    */
}

int main() {

    char search_for[5];

    printf("enter your word: ");
    fgets(search_for, 5, stdin);
    track_search(search_for);

    return 0;
}

$ gcc track.c && ./a.out

あなたの言葉を入力してください: に

の上

セグメンテーション違反

しかし、 puts(strstr(tracks[0], "on")); を使用すると puts(strstr(tracks[0], search_for)); の代わりに それはワインで動作しますが、どこが間違っているか知っていますか?

4

3 に答える 3

3

fgetsは改行を読み取るため、 に"on\n"見つからないため、に渡されるとセグメンテーション違反を引き起こす NULL を返し"one"ます。strstrputs

入力を読み取った後、最初に改行やその他の空白を削除することをお勧めします。たとえば、改行/スペースの最初の出現を 0 に設定します。

char *p;
if(p = strchr(search_for, '\n')) *p = 0;
if(p = strchr(search_for, ' ')) *p = 0;

( null ターミネータ用の追加の場所が必要char[5]なため、 にも十分ではありません。)"three"

于 2013-01-27T01:45:36.327 に答える
3

これにはいくつか問題があります。

まず、定数配列が正しく宣言されていません。

char tracks[][5] = {
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
};

これは、「 の任意の長さの配列を宣言しchar[5]ます。その配列の内容をよく見て、それらの文字列の長さが実際にはその文字数にゼロターミネータの 1 を加えたものであると考えてください。何かが飛び出しますか?おそらく単語"three"?それは 5+1、つまり5 ではなく6文字の幅になります。

これを試して:

const char *tracks[] = 
{
    "one",
    "two",
    "three",
    "four",
    "five",
    "six"
};

また、次のように for ループを変更します。

for (i = 0; i < sizeof(tracks)/sizeof(tracks[0]); ++i) 
{
    if (strstr(tracks[i], search_for))
        printf("track[%d]: %s\n", i, tracks[i]);
}

注:私は自分の正気を保つために、ループから冗長な「何も見つかりません」を引き出しました。

最後に、フェッチされた文字列には行末 ( '\n') が末尾に付加されている可能性が高く、その場合はそれを確認して null にする必要があります。入力バッファのサイズを大幅に長くし、endl がある場合は削除します。

int main()
{
    char search_for[64] = {0};

    printf("enter your word: ");
    if (fgets(search_for, sizeof(search_for), stdin))
    {
        size_t len = strlen(search_for);
        if (len && search_for[len-1] == '\n')
            search_for[len-1] = 0;
        track_search(search_for);
    }
    else
    {
        perror("fgets failed.");
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
于 2013-01-27T01:52:44.873 に答える
2

考慮しなければならないことが 2 つあります。

単語がリストにない場合、strstr() は NULL ポインターを返し、それを puts() に渡すことはできません。

 char *found = strstr(tracks[0], search_for);
if (found)
    puts(found);
else
    puts("The word '%s' was not found\n",search_for);

これを行うと、入力した改行も fgets が読み取ることがわかります。したがって、4 を入力して Enter キーを押すと、"four\n" が検索されます。したがって、その \n 文字を消去する必要があります。

char *p;
if ((p = strrchr(search_for, '\n')) != NULL) {
   *p = 0;
}

fgets で入力を読み取った後。

于 2013-01-27T01:49:04.827 に答える