scanf / getchar只在第一次循环时正常工作?

时间:2013-06-04 00:31:43

标签: c char buffer scanf getchar

我试图让用户输入他们想要的次数(并为每个数字创建一个链表节点)。

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

例如,使用下面的代码,终端显示:

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()方法应该可以工作。我错了吗?我也尝试过在“%c”之前和之后使用额外空格的scanf(),但无济于事。

3 个答案:

答案 0 :(得分:3)

您需要在scanf之后消化换行符。你可以在代码中做你正在做的事情:

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

答案 1 :(得分:2)

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

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

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

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");
    }
}

答案 2 :(得分:1)

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