31

我有这个,但是一旦它到达假定的 EOF,它就会再次重复循环和 scanf。

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

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

        return 0;
}
4

7 回答 7

24

尝试:

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

您需要将scanf输出与EOF

由于您在格式字符串中指定宽度15,因此您最多将读取 15 个字符。所以单词 char 数组应该是大小1615 +1对于nullchar)。所以声明为:

char words[16];
于 2010-09-21T20:09:50.607 回答
5

您的代码循环,直到它读取一个单词,然后退出。因此,如果你给它多个单词,它会读取第一个单词并退出,而如果你给它一个空输入,它将永远循环。无论如何,它只会从未初始化的内存中打印随机垃圾。这显然不是你想要的,但你想要什么?如果您只想阅读并打印第一个单词(如果存在),请使用 if:

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

如果你想循环,只要你能读一个单词,使用 while:

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

此外,正如其他人所指出的,您需要为单词数组提供足够大的大小以供您的 scanf 使用:

char word[16];

其他人建议测试 EOF 而不是检查 scanf 匹配的项目数。在这种情况下这很好,除非存在 EOF,否则 scanf 不会匹配失败,但在其他情况下(例如尝试读取整数)不太好,其中 scanf 可能不匹配任何内容而不达到 EOF(如果输入不是t 一个数字)并返回 0。

编辑

看起来你改变了你的问题以匹配我运行它时工作正常的代码 - 循环读取单词直到达到 EOF 然后退出。因此,您的代码正在发生其他事情,可能与您如何按照 David 的建议提供输入有关

于 2010-09-22T16:24:32.843 回答
5

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;
}
于 2010-09-21T20:09:59.873 回答
2

伙计,如果您使用的是 Windows,EOF则无法通过按 enter 来访问,而是通过在控制台上按Crtl+ 。Z这将打印“^Z”,一个EOF. 读取此内容时函数的行为(EOFCrtl+ Z):

功能 输出
scanf(...) EOF
gets(<variable>) NULL
feof(stdin) 1
getchar() EOF
于 2019-11-01T04:12:34.537 回答
0

您需要检查返回值EOF,而不是检查1

请注意,在您的示例中,您还使用了两个不同的变量名称wordsword,仅声明words了 ,并没有声明其长度,长度应为 16 以适应读入的 15 个字符加上一个NUL字符。

于 2010-09-21T20:09:21.683 回答
-1

我想最好的方法是......

int main()
{
    char str[100];
    scanf("[^EOF]",str);
    printf("%s",str);
    return 0;     
}
于 2013-12-05T14:16:03.643 回答
-6

对于 C 用户,这也可以

while ( gets(str) != NULL )
于 2013-01-21T18:18:47.513 回答