Подтвердить что ты не робот

Как вы читаете scanf, пока EOF в C?

У меня есть это, но как только он достигнет предполагаемого EOF, он снова повторяет цикл и scanf.

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

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

        return 0;
}
4b9b3361

Ответ 1

Try:

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

Вам нужно сравнить результат scanf с EOF

Поскольку вы указываете ширину 15 в строке формата, вы прочтете не более 15 char. Поэтому массив слов char должен иметь размер 16 (15 +1 для null char). Поэтому объявите его как:

char words[16];

Ответ 2

Scanf почти всегда больше проблем, чем стоит. Вот два лучших способа сделать то, что вы пытаетесь сделать. Этот первый - более или менее прямой перевод вашего кода. Это дольше, но вы можете посмотреть на него и четко увидеть, что он делает, в отличие от 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;
}

Ответ 3

Ваш код цикла, пока он не прочитает одно слово, а затем выйдет. Поэтому, если вы дадите ему несколько слов, он будет читать первый и выйти, а если вы дадите ему пустой ввод, он будет зацикливаться навсегда. В любом случае, он будет печатать только случайный мусор из неинициализированной памяти. Это, по-видимому, не то, что вы хотите, но чего вы хотите? Если вы просто хотите прочитать и распечатать первое слово (если оно существует), используйте, если:

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

Если вы хотите зацикливаться до тех пор, пока вы можете прочитать слово, используйте while:

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

Кроме того, как отмечали другие, вам нужно указать массив слов размером, достаточно большим для вашего сканирования:

char word[16];

Другие предложили тестирование EOF вместо проверки того, сколько элементов scanf соответствует. Это прекрасно для этого случая, когда scanf не может не совпадать, если нет EOF, но не так хорош в других случаях (например, для чтения целых чисел), где scanf не может ничего сопоставить без достижения EOF (если вход isn ' t число) и return 0.

изменить

Похоже, вы изменили свой вопрос в соответствии с моим кодом, который отлично работает, когда я его запускаю - циклы читают слова до тех пор, пока EOF не будет достигнут, а затем выйдет. Итак, что-то еще происходит с вашим кодом, возможно, связано с тем, как вы кормите его, как предложил Дэвид

Ответ 4

Вам нужно проверить возвращаемое значение на EOF, а не на 1.

Обратите внимание, что в вашем примере вы также использовали два разных имени переменной, words и word, объявили только words и не объявили свою длину, которая должна быть 16, чтобы соответствовать 15 символам, плюс символ NUL.

Ответ 5

Я думаю, лучший способ сделать это...

int main()
{
    char str[100];
    scanf("[^EOF]",str);
    printf("%s",str);
    return 0;     
}

Ответ 6

Для пользователей C это также будет работать

while ( gets(str) != NULL )