web-dev-qa-db-ja.com

CでEOFになるまでscanfをどのように読みますか?

これはありますが、想定されるEOFに達すると、ループとscanfを繰り返します。

int main(void)
{
        char words[16];

        while(scanf("%15s", words) == 1)
           printf("%s\n", words);

        return 0;
}
30
JJRhythm

試してください:

while(scanf("%15s", words) != EOF)

scanf出力をEOFと比較する必要があります

書式文字列で15の幅を指定しているため、最大で15文字を読み取ります。したがって、単語char配列のサイズは16null charの場合は15 +1)でなければなりません。次のように宣言します。

char words[16];
20
codaddict

Scanfは、それが価値があるよりもずっとずっと厄介です。ここに、あなたがやろうとしていることを行うための2つのより良い方法があります。この最初のものは、コードの多かれ少なかれ直接的な翻訳です。長いですが、scanfとは異なり、それを見て、それが何をするかを明確に見ることができます。

#include <stdio.h>
#include <ctype.h>
int main(void)
{
    char buf[1024], *p, *q;
    while (fgets(buf, 1024, stdin))
    {
        p = buf;
        while (*p)
        {
            while (*p && isspace(*p)) p++;
            q = p;
            while (*q && !isspace(*q)) q++;
            *q = '\0';
            if (p != q)
                puts(p);
            p = q;
        }
    }
    return 0;
}

そして、ここに別のバージョンがあります。検査でこれが何をするのかを見るのは少し難しいですが、行が1024文字より長い場合は壊れません。したがって、本番で使用するコードです。 (まあ、本当に本番で使用するのはtr -s '[:space:]' '\n'、しかしこれはあなたがそのような何かを実装する方法です。)

#include <stdio.h>
#include <ctype.h>
int main(void)
{
    int ch, lastch = '\0';
    while ((ch = getchar()) != EOF)
    {
        if (!isspace(ch))
            putchar(ch);
        if (!isspace(lastch))
            putchar('\n');
        lastch = ch;
    }
    if (lastch != '\0' && !isspace(lastch))
        putchar('\n');
    return 0;
}
4
zwol

コードは、1つのWordを読み取るまでループし、終了します。したがって、複数の単語を指定すると、最初の単語が読み取られて終了します。空の入力を指定すると、無限にループします。いずれの場合でも、初期化されていないメモリからランダムなガベージを出力するだけです。これは明らかにあなたが望むものではありませんが、あなたは何が欲しいですか?最初のWord(存在する場合)を読み取り、印刷する場合は、次の場合に使用します。

if (scanf("%15s", Word) == 1)
    printf("%s\n", Word);

Wordを読むことができる限りループする場合は、whileを使用します。

while (scanf("%15s", Word) == 1)
    printf("%s\n", Word);

また、他の人が指摘したように、Word配列にscanfに十分なサイズを与える必要があります。

char Word[16];

他の人は、scanfが一致したアイテムの数をチェックする代わりにEOFをテストすることを提案しました。 scanfがEOF(入力が数値でない場合))に到達せずに何も一致せず、0を返す場合(整数を読み取ろうとする場合など)。

編集

私のコードと一致するように質問を変更したように見えますが、実行するとうまくいきます-EOFに到達するまで単語を読んで終了します。デビッドによって提案された入力をどのように供給しているかに関連する

3
Chris Dodd

1に対してではなく、EOFに対して戻り値をチェックする必要があります。

この例では、wordsWordの2つの異なる変数名も使用し、wordsのみを宣言し、その長さは16〜読み込まれた15文字とNUL文字を合わせます。

0
Brian Campbell