如何使用fgets()通过c中的用户输入来控制while循环的执行? [英] How to use fgets() to control the execution of while loop through user input in c?

查看:83
本文介绍了如何使用fgets()通过c中的用户输入来控制while循环的执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用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.

PS:从fgets()输入中删除尾随换行符

这篇关于如何使用fgets()通过c中的用户输入来控制while循环的执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆