【问题标题】:User input with scanf using while loop使用while循环的scanf用户输入
【发布时间】:2021-05-19 08:54:51
【问题描述】:

我在使用while 循环时遇到了多个字符的问题。我正在编写一个代码,它将根据“y”或“n”的输入将用户引导到一个新函数。当我扫描一个字符时,它工作正常;但是,当用户输入多个字符时,while 循环会重复。

#include <stdio.h>
int main()
{
    char x;
    printf("type in letter n or y\n");
    scanf("%c", &x);
    while (x!= 'Y' && x!='N' && x!= 'n' && x!='y')
    {
        printf("Invalid, please type Y/N to continue: \n");
        scanf(" %c", &x);
    }
    if (x== 'Y' || x == 'y')
    {
        printf("y works");
    }
    if (x =='N' || x =='n')
    {
        printf("n works");     
    }
}

例如,如果我输入hoyp,它会说“无效,...”两次,然后“y 有效”将写在第三行。如何修改代码,让无效的只说一次,用户必须重新输入才能让程序继续运行?

【问题讨论】:

标签: c


【解决方案1】:

这就是scanf 的行为方式。它会继续读取您输入的所有字符。您可以先使用fgets 接受字符串作为输入,然后仅提取和检查其第一个字符。 fgets 允许您指定要读取的确切字符数。我首先声明了一个大小为 4096 的 char 数组。这将在输入最多 4095 个字符时起作用。您可以根据需要调整大小。

#include <stdio.h>
int main()
{   
    char x, buffer[4096];   
    printf("type in letter n or y\n");
    fgets(buffer, 4096, stdin);
     x = buffer[0];
     while (x!= 'Y' && x!='N' && x!= 'n' && x!='y')            
     {        
         printf("Invalid, please type Y/N to continue: \n");         
         fgets(buffer, 4096, stdin);
         x = buffer[0];         
     }        
     if (x== 'Y' || x == 'y')          
     {           
         printf("y works");
     }           
     if (x =='N' || x =='n')        
     {           
         printf("n works");           
     }  
 } 

【讨论】:

  • 由于缓冲区大小,您的fgets 仍然只能读取一个字符,因此这并不能解决问题。
  • 使用char buffer[4096];if (fgets(buffer, sizeof(buffer), stdin) != NULL) — 如果您认为 4096 太小,可以增加数组大小。您应该始终检查输入操作是否成功,因此需要进行 if 测试。
  • @interjay 谢谢。我已经修好了
  • 谢谢,我已经解决了这个问题,这个解决方案适用于例如“gyoh”,但不适用于“yesno”,因为它只需要第一个字符,我通过添加 || 解决了这个问题string0[1] != '\n') 用于 while 函数,&& string0[1] == '\n') 用于 if 函数。谢谢。
【解决方案2】:

这是我解决问题的方法:

  1. 我使用了fgets() 而不是scanf()。看看为什么 here
  2. 我使用了question中用户jamesdlin和MM的建议,解决了输入多于一个字符或输入为空时的重复打印问题。我鼓励您阅读整个主题以了解有关此问题的更多信息。
  3. (可选)使用了一些额外的头文件以提高循环条件下的代码可读性。我认为fgets() 可以在while() 的条件下使用,但我已经习惯了我在下面写的模式。

编辑:添加了拒绝长度 > 1 的输入的条件。以前,无论长度如何,都将接受以“y”或“n”开头的输入(并分别解释为“y”或“n”) .


#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>

void clearInput();

int main()
{   
    // allocate space for 'Y' or 'N' + '\n' + the terminator '\0'
    // only single inputs will be accepted
    char _inputbuff[3];
    char choice;
    bool isValidInput = false;

    
    while(!isValidInput) {
        printf("Please enter your input[y/n]: ");
        
        // use fgets() instead of scanf
        // this only stores the first 2 characters of the input
        fgets(_inputbuff, sizeof(_inputbuff), stdin);
        
        // don't accept empty input to prevent hanging input
        if(_inputbuff[0] == '\n') {
            printf("Empty input\n");
            // go back to the top of the loop
            continue;
        }
        
        // input is non-empty
        
        // if the allocated space for the newline does not
        //  contain '\n', reject the input
        if(_inputbuff[1] != '\n') {
            printf("Input is more than one char.\n");
            clearInput();
            continue;
        }
        
        choice = _inputbuff[0];
        // printf("The input is %c\n", choice);
        
        // convert the input to uppercase for a 'cleaner' code
        //  during input validation
        choice = toupper(choice);
        
        // the input is not 'Y' or 'N'
        if(choice != 'Y' && choice != 'N') {
            printf("Please choose from Y or N only.\n");
            
            // go back to the top of the loop
            continue;
        }
        
        // the input is 'Y' or 'N', terminate the loop
        isValidInput = true;
    }
    
    // conditions for 'Y' or 'N'
    
    if(choice == 'Y') {
        printf("The input is Yes.\n");
        return 0;
    }
    
    if(choice == 'N') {
        printf("The input is No.\n");
        return 0;
    }
}  

void clearInput() {
        int _clear;
        // clear input stream to prevent repeated printing of invalid inputs
        while ((_clear = getchar()) != '\n' && _clear != EOF ) { }
}

(这是我第一次回答问题,自从我使用 C 以来已经有一段时间了,所以请随时就我的回答提出建议/更正。谢谢!)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-08
    • 2013-11-16
    • 2020-02-15
    • 2019-12-05
    • 1970-01-01
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    相关资源
    最近更新 更多