fgets 指令被跳过。为什么?

发布于 2024-09-02 17:49:13 字数 122 浏览 5 评论 0原文

每当我在 fgets 之前执行 scanf 时, fgets 指令就会被跳过。我在 C++ 中遇到过这个问题,我记得我必须有一些指令来清除标准输入缓冲区或类似的东西。我想 C 也有一个等价的东西。它是什么?

谢谢。

Whenever I do a scanf before a fgets the fgets instruction gets skipped. I have come accross this issue in C++ and I remember I had to had some instrcution that would clear the stdin buffer or something like that. I suppose there's an equivalent for C. What is it?

Thanks.

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

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

发布评论

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

评论(3

燕归巢 2024-09-09 17:49:13

我敢打赌这是因为 \n 卡在输入流中。

请参阅以下问题之一:

我无法刷新标准输入。
我该如何在此处刷新 STDIN?
scanf() 导致无限循环

这个答案

另外:为什么不使用 scanf()

PS fgets() 是一个函数,而不是一条指令。

I'll bet it's because of the \n stuck in the input stream.

See one of these questions:

I am not able to flush stdin.
How do I go about Flushing STDIN here?
scanf() causing infinite loop

or this answer.

Also: Why not to use scanf().

P.S. fgets() is a function, not an instruction.

情绪少女 2024-09-09 17:49:13

调用 scanf() 之后的 fgets() 函数可能1不会被跳过。 可能1在输入流中发现换行符后立即返回。

fgets() 之前调用 scanf() 几乎总是会导致 scanf() 留下未使用的换行符 ('\n') 在输入流中,这正是 fgets() 正在寻找的。

为了混合 scanf()fgets(),您需要从调用 scanf() 中删除留下的换行符输入流。

刷新标准输入(包括换行符)的一种解决方案将类似于以下内容:

int c;
/* discard all characters up to and including newline */
while ((c = getchar()) != '\n' && c != EOF); 

1 - 在没有看到实际代码的情况下很难确定。


或者,如 Jerry Coffin 在下面的评论中建议,您可以使用 scanf("%*[^\n]");"%*[^\n]" 指令指示 scanf() 匹配非换行符并禁止分配转换结果。

/* match up to newline */
scanf("%*[^\n]"); 
/* discard the newline */
scanf("%*c"); 

来自http://c-faq.com/stdio/gets_flush1.html

带有 “%*[^\n]” 的初始 scanf() 要么吃掉所有内容,但不包括换行符,要么失败。后续的“%*c”(或普通的旧getchar())将消耗换行符(如果有的话)。

最后一个“如果”也很重要:也许用户发出了 EOF 信号。在这种情况下,getchar()scanf("%*c") 可能——这个决定留给编写编译器的人——要么立即返回EOF,或者返回给用户以获取更多输入。如果实现者选择后者,用户可能必须额外单击一次“结束这件事”(^D、^Z、鼠标按钮、前面板开关或其他)。如果没有别的的话,这很烦人。


或者,正如 Chris Dodd 在下面的评论中建议的那样,您可以使用 scanf("%*[^ \n]%*1[\n]");"%*[^\n]%*1[\n]" 指令指示 scanf() 匹配非换行符,然后匹配一个换行符并抑制转换结果的赋值。

/* match and discard all characters up to and including newline */
scanf("%*[^\n]%*1[\n]");

The fgets() function following the call to scanf() is probably1 not getting skipped. It is probably1 returning immediately having found a newline in the input stream.

Calling scanf() before fgets() almost always results in scanf() leaving an unused newline ('\n') in the input stream, which is exactly what fgets() is looking out for.

In order to mix scanf() and fgets(), you need to remove the newline left behind by the call to scanf() from the input stream.

One solution for flushing stdin (including the newline) would be something along the lines of the following:

int c;
/* discard all characters up to and including newline */
while ((c = getchar()) != '\n' && c != EOF); 

1 - It is difficult to be certain without seeing the actual code.


Or, as Jerry Coffin suggested in his comment below, you could use scanf("%*[^\n]");. The "%*[^\n]" directive instructs scanf() to match things that are not newlines and suppress assignment of the result of the conversion.

/* match up to newline */
scanf("%*[^\n]"); 
/* discard the newline */
scanf("%*c"); 

From http://c-faq.com/stdio/gets_flush1.html:

An initial scanf() with “%*[^\n]” will either eat everything up to but not including a newline, or fail. A subsequent “%*c” (or plain old getchar()) will consume the newline, if there was one.

That last “if” matters too: perhaps the user signalled EOF. In this case, the getchar() or scanf("%*c") might -- this decision is left to the people who write your compiler -- either immediately return EOF, or go back to the user for more input. If the implementors choose the latter, the user might have to click on “end this thing” (^D, ^Z, mouse button, front panel switch, or whatever) one extra time. This is annoying, if nothing else.


Or, as Chris Dodd suggested in his comment below, you could use scanf("%*[^\n]%*1[\n]");. The "%*[^\n]%*1[\n]" directive instructs scanf() to match things that are not newlines and then match one newline and suppress assignment of the results of the conversion.

/* match and discard all characters up to and including newline */
scanf("%*[^\n]%*1[\n]");
转身泪倾城 2024-09-09 17:49:13

您可以将此行放在 fgets() 调用之前,这样就会在您按 enter 时生成尾随 '\n'

scanf("%c", (char *) stdin);

You can just put this line before your fgets() call and that'll get the trailing '\n' generated when you pressed enter

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