在C语言中如何读取scanf直到EOF?

发布于 2024-09-24 01:50:25 字数 209 浏览 3 评论 0原文

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

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

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

        return 0;
}

I have this but once it reaches the supposed EOF it just repeats the loop and scanf again.

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

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

        return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

最冷一天 2024-10-01 01:50:25

尝试:

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

您需要将 scanf 输出与 EOF 进行比较,

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

char words[16];

Try:

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

You need to compare scanf output with EOF

Since you are specifying a width of 15 in the format string, you'll read at most 15 char. So the words char array should be of size 16 ( 15 +1 for null char). So declare it as:

char words[16];
无名指的心愿 2024-10-01 01:50:25

您的代码会循环直到读取一个单词,然后退出。因此,如果你给它多个单词,它会读取第一个单词并退出,而如果你给它一个空输入,它将永远循环。无论如何,它只会打印未初始化内存中的随机垃圾。这显然不是你想要的,但是你想要什么?如果您只想读取并打印第一个单词(如果存在),请使用 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,然后退出。所以你的代码发生了其他事情,可能与你如何按照大卫的建议向其提供输入有关

Your code loops until it reads a single word, then exits. So if you give it multiple words it will read the first and exit, while if you give it an empty input, it will loop forever. In any case, it will only print random garbage from uninitialized memory. This is apparently not what you want, but what do you want? If you just want to read and print the first word (if it exists), use if:

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

If you want to loop as long as you can read a word, use while:

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

Also, as others have noted, you need to give the word array a size that is big enough for your scanf:

char word[16];

Others have suggested testing for EOF instead of checking how many items scanf matched. That's fine for this case, where scanf can't fail to match unless there's an EOF, but is not so good in other cases (such as trying to read integers), where scanf might match nothing without reaching EOF (if the input isn't a number) and return 0.

edit

Looks like you changed your question to match my code which works fine when I run it -- loops reading words until EOF is reached and then exits. So something else is going on with your code, perhaps related to how you are feeding it input as suggested by David

爱殇璃 2024-10-01 01:50:25

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;
}

Scanf is pretty much always more trouble than it's worth. Here are two better ways to do what you're trying to do. This first one is a more-or-less direct translation of your code. It's longer, but you can look at it and see clearly what it does, unlike with 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;
}

And here's another version. It's a little harder to see what this does by inspection, but it does not break if a line is longer than 1024 characters, so it's the code I would use in production. (Well, really what I would use in production is tr -s '[:space:]' '\n', but this is how you implement something like that.)

#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;
}
沦落红尘 2024-10-01 01:50:25

伙计,如果您使用的是 Windows,则不能通过按 Enter 来到达 EOF,而是通过在控制台上按 Crtl+Z 来到达。这将打印“^Z”,这是 EOF 的指示符。读取此内容时函数的行为(EOFCrtl+Z):

函数输出
scanf(...)EOF
gets(<变量>)NULL
feof(stdin)1 >
getchar()EOF

Man, if you are using Windows, EOF is not reached by pressing enter, but by pressing Crtl+Z at the console. This will print "^Z", an indicator of EOF. The behavior of functions when reading this (the EOF or Crtl+Z):

FunctionOutput
scanf(...)EOF
gets(<variable>)NULL
feof(stdin)1
getchar()EOF
dawn曙光 2024-10-01 01:50:25

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

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

You need to check the return value against EOF, not against 1.

Note that in your example, you also used two different variable names, words and word, only declared words, and didn't declare its length, which should be 16 to fit the 15 characters read in plus a NUL character.

留一抹残留的笑 2024-10-01 01:50:25

我想做到这一点的最好方法是......

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

I guess best way to do this is ...

int main()
{
    char str[100];
    scanf("[^EOF]",str);
    printf("%s",str);
    return 0;     
}
躲猫猫 2024-10-01 01:50:25

对于 C 用户,这也适用

while ( gets(str) != NULL )

For C users, this will also work

while ( gets(str) != NULL )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文