【问题标题】:scanf/getchar working correctly only first time through loop? [duplicate]scanf/getchar 只有第一次通过循环才能正常工作? [复制]
【发布时间】:2013-05-30 06:27:29
【问题描述】:

我试图让用户根据需要多次输入一个数字(并为每个数字创建一个链表节点)。

但是,我尝试了多种清除字符输入缓冲区的方法,但都无济于事。奇怪的是,代码将执行一次,但第二次无法正确执行。

例如,使用下面的代码,终端读取:

would you like to enter an integer?
y
Enter an integer: 4
would you like to enter an integer?
y
**program terminates**

在我使用scanf("%c", yesno); 之前,我什至无法在最后一行输入“y”。它刚刚终止。

struct node *read_numbers(void){
    struct node *first = NULL;
    int n; char yesno;
    yesno = 'y';
    while( yesno == 'y'){
        printf("Would you like enter an integer ((y) for yes/(n) for no):\n");
        yesno = getchar();  
        while(getchar() != '\n');
        if(yesno == 'y'){
            printf("Enter an Integer:");
            scanf(" %d", &n);
            first = add_to_list(first, n);
            } else {
                return first;
                }
        } // end while
    }

我阅读了字符输入和缓冲区,据说 getchar() 方法应该可以工作。我用错了吗?我也试过 scanf() 在“%c”前后有额外的空格,但无济于事。

【问题讨论】:

    标签: c char buffer scanf getchar


    【解决方案1】:

    您需要在 scanf 之后消化换行符。您可以在代码中执行上述操作:

    scanf(" %d", &n);
    while(getchar() != '\n');
    first = add_to_list(first, n);
    

    【讨论】:

    • 成功了!为什么我在scanf() 之后还需要while(getchar() != '\n');,如果……我正在使用scanf()(vs getchar())?
    • @Gnuey 因为 scanf 将扫描字符串,直到找到一个空白字符,但该字符将留在读取缓冲区中。 getchar() 从该缓冲区读取,因此它将读取您的换行符并退出 while 循环。 scanf 很笨重。大多数人使用 fgets+sscanf 来完成你的代码所做的事情
    • 啊,我明白了。谢谢!
    【解决方案2】:

    我可以建议您使用fgets 作为getcharscanf 的更安全替代方案吗?

    正如您所注意到的,这些函数可以缓冲换行符并将其传递给从标准输入读取的下一个函数。

    使用fgets,您可以将输入存储在一个字符数组中并避免此类问题。此外,您仍然可以轻松检查输入是否仅包含换行符:

    char user_input[10] = "";
    
    printf("Would you like enter an integer ((y) for yes/(n) for no):\n");
    
    /* get input or quit if only newline is entered, we only check the first char */
    while(fgets(user_input, 3, stdin)[0] != '\n') 
    {
        /* check if the first char is 'y', quicker to do than using strcmp */
        if(user_input[0] == 'y') 
        {
            int input = 0;
    
            printf("Enter an Integer: ");
    
            fgets(user_input, 5, stdin); /* get input again */
    
            input = atoi(user_input);    /* convert to int */
    
            printf("Your integer is %d\n", input);
    
            printf("Would you like to go again? y/n:\n");
        }
        else
        {
            return printf("No input there.\n");
        }
    }
    

    【讨论】:

    • 啊,我明白了!这确实工作得很好。点赞,谢谢。
    【解决方案3】:

    getchar是从标准输入中获取数据,while(getchar() != '\n');就像清除标准输入缓冲区一样。 所以下面的代码可以正常工作

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-03
      • 1970-01-01
      • 1970-01-01
      • 2015-09-24
      • 2016-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多