如何使用fgets()通过c中的用户输入来控制while循环的执行? [英] How to use fgets() to control the execution of while loop through user input in c?
问题描述
我正在尝试用c编写程序,其中我可以通过来自stdin的用户输入来控制while循环执行.我已经通过scanf和getchar函数成功完成了它.现在,我尝试使用fgets()函数(建议广泛使用而不是scanf()函数)复制此函数.我写了以下代码:
I am trying to write a program in c wherein I can control the while loop execution through user input from stdin. I have done it successfully through scanf and getchar functions. Now I am trying to replicate this using the fgets() function which is widely recommended to use rather than scanf() function. I wrote the following code:
#include<stdio.h>
#include<string.h>
int main()
{
char loop[4]= "yes";
printf("%s\n",loop);
while(strcmp(loop,"yes")==0)
{
printf("Do you want to continue? [yes|no]: ");
fgets(loop,4,stdin);
}
}
在终端的输出中,我得到以下信息:
In the output in terminal, I get the following:
Do you want to continue? [yes|no]: yes
Do you want to continue? [yes|no]:
我得到继续循环的提示,当我键入"no"时,它会按原样停止,但是一旦我键入"yes",该循环就会执行一次,然后停止.
I get prompt for continuing the loop, when I type 'no', it stops as it should do, but as soon as I type 'yes', the loop executes one time and then stops.
我猜是问题在于,一旦按下回车键,fgets()便将其存储到循环变量中,这就是while循环终止的原因.我在想正确的方向吗?如果是的话,在这种情况下,如何摆脱这个多余的字符"Enter".
I guess that the problem is that as soon as I press enter, fgets() stores this into loop variable, and that is why the while loop terminates. Am I thinking in right direction? If yes, how can I get rid of this extra character which is "Enter" in this case.
推荐答案
更改此内容:
fgets(loop, 4, stdin);
对此:
fgets(loop, 5, stdin);
然后,当然,将缓冲区的大小设置为5,例如 char loop [5] ="yes";
,以便存储单词"yes"的3个字符,换行符 fgets()
将被读取(自是读行,对吧?)和字符串NULL终止符(如您所知).
after, of course, setting the size of your buffer to 5, like this char loop[5]= "yes";
, in order to store the 3 characters of the word "yes", the newline fgets()
will read (since it's reading lines, right?), and the string NULL-terminator (as you already know).
要解释代码的行为,您必须了解@DavidBowling的注释:
To explain the behavior of your code, you have to understand @DavidBowling's comment:
请注意,通过使用
fgets(loop,4,stdin);
,当输入是"时,换行符将留在输入流中,因此下一个输入调用将拾取此换行符.
Note that by using
fgets(loop, 4, stdin);
, the newline is left in the input stream when "yes" is entered, so the next input call picks up this newline character.
使用此程序演示:
#include<stdio.h>
#include<string.h>
int main()
{
char loop[4]= "yes";
while(strcmp(loop,"yes")==0)
{
printf("Do you want to continue? [yes|no]: ");
fgets(loop, 4, stdin);
printf("|%s|\n",loop); // I surrounded the output, in order to catch the newline
}
return 0;
}
输出:
Do you want to continue? [yes|no]: yes
|yes|
Do you want to continue? [yes|no]: |
|
表示换行符保留在标准输入(STDIN)缓冲区中,并在第二次调用 fgets()
时被占用.从该方法的参考:
which shows that the newline character is left in the Standard Input (STDIN) buffer, and gets consumed with the second call to fgets()
. From the reference of the method:
从流中读取字符,并将它们作为C字符串存储到str中,直到已读取(num-1)个字符或到达换行符或到达文件末尾为止,以先到者为准.
Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or the end-of-file is reached, whichever happens first.
在复制到str的字符之后会自动附加一个终止的空字符.
A terminating null character is automatically appended after the characters copied to str.
让我们一步一步看看:
您键入yes,然后按Enter,这将使标准输入"缓冲区看起来像这样:
You type yes, and then hit Enter, which makes the Standard Input buffer look like this:
------------------
| y | e | s | \n |
------------------
现在执行了对 fgets(loop,4,stdin);
的第一次调用,这意味着该方法将尝试从STDIN读取3(4-1)个字符.它读取 y
, e
和 s
,将它们从STDIN的缓冲区移到您声明的程序缓冲区,称为 loop
,然后附加字符串NULL终止符.
and now the first call to fgets(loop, 4, stdin);
gets executed, which means that the method will try to read 3 (4 - 1) characters from STDIN. It reads y
, e
and s
, moves them from STDIN's buffer to your program's buffer you declared, named loop
, and then appends the string NULL terminator.
现在STDIN缓冲区是:
Now the STDIN buffer is:
------------------
| \n | | | |
------------------
并且在用户有机会输入之前,将执行 fgets(loop,4,stdin);
(这是方法的职责,因为它们是在STDIN中等待的数据)要消耗的缓冲区-如果没有数据,则该方法将耐心等待用户输入某些内容...).
and before the user has a chance to input, fgets(loop, 4, stdin);
is going to be executed (it's the method's duty to do so, since they are data waiting in STDIN's buffer to be consumed - if there were no data, then the method would patiently wait for the user to input something...).
现在,它将换行符复制到 loop
中,并在此停止,因为现在STDIN缓冲区为空,并最终将字符串NULL终止符附加到 loop
(在索引处)1).
Now, it copies the newline character into loop
, stops there, since now the STDIN buffer is empty, and eventually appends a string NULL terminator to loop
(at index 1).
现在STDIN缓冲区为空:
and now the STDIN buffer is empty:
-----------------
| | | | |
-----------------
因为用户没有更多输入-代码循环在while循环之后移动,因为当 loop
是一个以换行符为第一个字符的字符串时,循环的条件为false
since there was no more input by the user - the code's flow moved after the while loop, since the loop's condition evaluated to false, when loop
was a string with the newline character as its first character.
这篇关于如何使用fgets()通过c中的用户输入来控制while循环的执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!