bugfix> c > 投稿

私はただCを学んでいるだけで、基本的な理解の問題に直面しています。私がやろうとしているのは、入力と同じ回数Xを印刷することです。入力はすべて同じ行にあり、今はうまく機能しています。

私が直面している問題は、プログラムを終了することです。私がやろうとしているのは、行が読み取られた後にプログラムを終了させることです。

例:入力1 2 3

出力:

X
XX
XXX

プログラム終了

今、私は永遠にループにいます...

誰も私がここで見逃している概念を説明しようとすることはできますか?それは構文の問題かもしれないと確信していますが、私は本当に自分のロジックがどこで間違っているのかを理解しようとしています。

この場合、EOFはどのように機能しますか?

   int main(void)
{
int i;
int n = 0;
while ( n  != EOF ) {
scanf( "%d",&n );
    if (n == EOF){
    break;
    }
        for ( i=0; i<n; i++){
        printf("X");
    }
    printf("\n");
}
}

回答 1 件
  • あなたがやろうとしている方法ではなく、あなたがしようとしていることを行うことができます...

    まず、 scanf の戻り値を常に検証する必要があります 。次の3つのケースから保護する必要があります。

    EOF  返される-入力が検出される前に入力の終わりに到達したことを意味します(これを押すと、ユーザーが手動で生成できますCtrl + d (またはCtrl + z 窓の上1));

    未満の場合、変換指定子の数が返されますマッチング または入力 失敗(これが発生すると、ストリームからの文字の抽出が停止し、君は 次の読み取りを試みる前に、無関係な文字を削除する責任があります)。または

    戻り値は変換指定子の数に等しくなります-データが変換され、指定した各変数に格納されたことを示します。

    さらに、受け取った入力が許容範囲内であることを検証する必要があります。 (おそらく望んでいない 値を入力します。

    コードについては、上記の(3)を検証して EOF で終了するだけです。 、またはマッチング または入力 失敗-1種類のデータ( integers )および障害が発生すると終了できます。

    しかし、それはあなたの問題を解決しません。この問題に対処する正しい方法は、一度に1行のデータを読み取ることです( fgets  またはPOSIX getline )その後、 strtol を繰り返し呼び出して、データ行の各整数値を解析します  そして、その endptr を利用する  パラメータを使用して、行全体を処理します。 (SOの適切な使用に関する多くの例があります)

    ただし、各 int を読んだ後に次の文字をチェックするだけで、やりたいことを実行することもできます。   getchar() と  そして、それが '\n' である場合 、それからあなたの読み取りが完了し、そうでなければあなたはキャラクターを戻す で stdin   ungetc を使用する  プットバックの検証は何によって成功しましたか? (ヒント:帰る -すべてのCライブラリ関数の戻り値は、それに関連付けられている man page に明確に記述されています  - :) を使用

    まとめると、次のようなことができます。

    #include <stdio.h>
    int main (void) {
        int i, n;
        printf ("input: ");
        while (scanf ("%d", &n) == 1) { /* validate the 'return' of scanf */
            if (n < 0) {    /* validate n not negative */
                fprintf (stderr, "error, input cannot be negative.\n");
                return 1;
            }
            for (i = 0; i < n; i++)     /* then loop that number of times   */
                putchar ('X');          /* don't printf 1-char, use putchar */
            putchar ('\n');             /* tidy up with newline */
            i = getchar();      /* read next char in stdin */
            if (i == '\n')      /* if end of line - break (done) */
                break;
            else if (ungetc (i, stdin) != i) {  /* validate putting it back */
                fprintf (stderr, "error: putting char back in stdin.\n");
                return 1;
            }
        }
        return 0;
    }
    
    

    使用例/出力例

    $ ./bin/output_x
    input: 1 2 3
    X
    XX
    XXX
    
    

    または

    $ ./bin/output_x
    input: 7 1 1 5 1 1 1
    XXXXXXX
    X
    X
    XXXXX
    X
    X
    X
    
    

    物事を見て、さらに質問がある場合は私に知らせてください。

    脚注

    しかし、参照してください:Ctrl + ZはWindows 10でEOFを生成しません

あなたの答え