【问题标题】:How to properly get a y/n input in C如何在 C 中正确获取 y/n 输入
【发布时间】:2018-01-25 14:57:37
【问题描述】:

所以,我是一个 C 和编程新手,我正在尝试编写一个函数来在一个使用大量 y/n 选择的程序中抽象化它们,到目前为止,我有这样的:

void chooser (char *choice)
{
    while (1)
    {
        *choice='\0';
        *choice=getchar();
        while(getchar()!='\n');

        if(*choice == 'y' || *choice == 'n')
            break;
    }
}

第二个 getchar 在标准输入中消耗过多的输入,因此它不应该受到用户输入乱码的影响。

唯一的问题是,如果我键入“ywhatever”或“nwhatever”,第一个 getchar 仍会捕获“y”和“n”并将其传递给 main。 我想拥有它,这样用户就必须输入“y”或“n”而不是别的。 我可以尝试放弃 getchar 并切换到 fgets 进行捕获和 sscanf 进行解析,这是我更喜欢获取字符串的方式,但是,不知道,它只是一个字符,我不想让事情变得过于复杂。

有没有办法在用户输入后扫描标准输入以查看它是否包含多个字母字符?

编辑: 最后,我选择了这个:

int chooser ()
{
    char buffer[MAXIN];    

    while (1)
    {
        printf("y/n: ");
        if (fgets(buffer, sizeof(buffer), stdin)!=NULL)
        {   
            if (buffer[0] == 'y' || buffer[0] == 'n')
            {
                if (buffer[1]=='\n')
                {
                    break;
                }
                else
                {
                    while(getchar()!='\n');
                }
            }
        }
    }

    if (buffer[0]=='y')
    {
        return 1;
    }
    if (buffer[0]=='n')
    {
        return 0;
    }
}

它似乎正在做我需要它做的事情,还有什么我应该调整的吗?来自标准输入的 fgets 是否需要 if(fgets(...)!=NULL) 检查?

【问题讨论】:

  • 你试过 fgetc 吗?
  • fgets 返回NULL 以防遇到EOF 或发生某些读取错误。添加检查NULL -> if(fgets(buffer, sizeof(buffer), stdin) != NULL) {..
  • 好的,谢谢,我知道fgets通常需要检查,但是在这种情况下它是从用户输入中读取的,那么它仍然可能遇到读取错误吗?我可以输入什么让 fgets 发疯? :')
  • 为什么不让选择器返回一个 int 并将 YES 和 NO 定义为常量。看起来简单多了。您的来电者必须担心大小写、本地化(我知道对您来说可能并不重要)
  • 你说得对,我想我会那样做,这样我就可以主要去“ if (chooser()==1) ”,我认为它更线性。

标签: c stdin getchar


【解决方案1】:

这个解决方案有什么问题:

#include <stdio.h>

void chooser(char *choice)
{
  char buffer[200];    
  while (1)
  {
    fgets(buffer, sizeof(buffer), stdin);        
    if (buffer[0] == 'y' || buffer[0] == 'n')
      break;
  }    
  *choice = buffer[0];
}

int main(int argc, char **argv)
{
  while (1)
  {
    char yn;
    chooser(&yn);    
    if (yn == 'y' || yn == 'n')
      printf("User choice: %c\n", yn);
  }
}

这并不完全是“过于复杂”

还有改进的余地,例如这里根本没有处理EOF条件。

执行示例:

abc
def
y
User choice: y
n
User choice: n
yes
User choice: y
no
User choice: n
noooo
User choice: n

【讨论】:

  • 没什么,我点击错了 ;-) 但是,您选择的缓冲区大小是任意的吗?
  • @BenjaminBarrois 是的,无论如何我们希望yn 之后的所有内容都被丢弃。
  • 如果您打算这样做,至少让chooser 函数返回一个布尔值。在两个地方检查“y”或“n”对我来说似乎很愚蠢。此外,fgets() 在这里是错误的选择。如果用户输入多个字符,您的缓冲区将溢出。
  • @BenjaminBarrois 实际上缓冲区大小必须至少为 2(一个用于字符,一个用于 NUL 字符串终止符)。
  • @JonathanWood 不,不会有缓冲区溢出,多余的字符将被丢弃,这就是我们想要的。
猜你喜欢
  • 2020-09-17
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
  • 2014-03-08
  • 2021-09-17
  • 1970-01-01
  • 1970-01-01
  • 2017-10-11
相关资源
最近更新 更多