0

そのような getword の例に出くわしました。私はすべてのチェックなどを理解していますが、ungetc に問題があります。

c満たしif ((!isalpha(c)) || c == EOF)、また満たさない場合while (isalnum(c)) -> それは文字でも数字でもありません - それungetcを拒否しcharます。

だとしましょう'\n'

その後、取得しreturn wordますが、配列に保存されていないため、返すことはできません。その後どうなりますか?

    while (isalnum(c)) {
        if (cur >= size) {
            size += buf;
            word = realloc(word, sizeof(char) * size);

        }
        word[cur] = c;
        cur++;
        c = fgetc(fp);
    }
    if ((!isalpha(c)) || c == EOF) {
        ungetc(c, fp);          
    }
    return word;

EDIT @Mark Byers - ありがとう、しかしその c は目的のために拒否され、無限ループで何度も条件を満たさないでしょうか?

4

3 に答える 3

1

ungetc文字をストリームにプッシュして、次の読み取りでその文字が再び返されるようにします。

ungetc(c, fp);  /* Push the character c onto the stream. */
/* ...etc... */
c = fgetc(fp);  /* Reads the same value again. */

これは、現在のトークンがいつ完成したかを知るために文字を読み取っているが、まだ次のトークンを読み取る準備ができていない場合に便利な場合があります。

于 2012-08-28T20:09:49.130 に答える
1

わからない線の直前の端末状態がイマイチ。おそらく次のようになります。

int c;

...

if (!isalpha(c) && c != EOF)
    ungetc(c, fp);

これは、最後に読み取られた文字が実際の文字 (EOF ではない) であり、アルファベット文字ではない場合、入力ストリームを次に使用するものによって再処理するためにプッシュバックすることを意味しますfp。つまり、空白を読んだとします。空白はループを終了し、空白は押し戻されて、次のものgetc(fp)が再び空白を読み取るようになります (fscanf()またはfread()ファイルストリームに対するその他の読み取り操作と同様fp)。空白の代わりに EOF を取得した場合、修正したコードで EOF を押し戻す試みはありません。元のコードでは、EOF が押し戻されます。

ではなく でcなければならないことに注意してください。intchar

于 2012-08-28T20:11:33.350 に答える
0

わかった。今、私はその理由を理解しています。'\n'私を悩ませていました。私はばかで、main()getword を参照するセクションを忘れていました。もちろん、getword を呼び出す前にいくつかのテスト (別のテストungetcがあります) があり、fputsその文字は満足していません。isalnum このことから、whileループインはgetword常に少なくとも 1 つのisalnum肯定で開始され、その後のチェックは次の文字に対してのみ行われることがわかります。

于 2012-08-28T20:47:08.630 に答える