Scanf递归函数触发printf两次?

Scanf递归函数触发printf两次?,c,scanf,C,Scanf,我正在尝试创建一个函数来获取用户输入,它可以是“y”或“n” #包括 #包括“userinput.h” bool userinput\u get\u yes\u或\u no(char消息[]){ printf(“%s[y/n]:\n”,消息); 答案; scanf_s(“%c”和答案,1); 如果(答案='y')返回true; 如果(答案='n')返回false; 返回userinput\u get\u yes\u或\u no(消息); } 当用户只输入“y”、“n”时,效果非常好。 当您输入

我正在尝试创建一个函数来获取用户输入,它可以是“y”或“n”

#包括
#包括“userinput.h”
bool userinput\u get\u yes\u或\u no(char消息[]){
printf(“%s[y/n]:\n”,消息);
答案;
scanf_s(“%c”和答案,1);
如果(答案='y')返回true;
如果(答案='n')返回false;
返回userinput\u get\u yes\u或\u no(消息);
}
当用户只输入“y”、“n”时,效果非常好。 当您输入任何其他内容(但仅输入1个字符)时,它会重复问题,并打印消息一次

但是 当您输入任何长度超过1个字符的内容时,在等待再次输入之前,消息会重复多次(与您输入的字符数相同)


我做错了什么?

我复制了您的问题-基本上,您的控件正在流入下一次函数调用,并在stdin队列中找到了一些内容。我找到了一个有用的答案,并将其添加到您的函数中:

bool userinput_get_yes_or_no(char message[])
{
    char answer;
    char c; /* for discard */
    printf("%s [y/n]: \n", message);
    scanf_s(" %c", &answer, 1);
    while((c = getchar()) != '\n' && c != EOF); /* discard */
    if (answer == 'y') {
        return true;
    }
    else if (answer == 'n') { 
        return false;
    }
    else {
        return userinput_get_yes_or_no(message);
    }
}

为了便于阅读,我稍微更改了控制流,可以随意忽略。重要的部分是标记为discard的行,在该行中,我们丢弃了缓冲区的其余部分,以确保没有任何东西等待下一次调用函数。

假设(因为这样可以测试和确认/拒绝):字符已经输入到控制台/std中,并且在使用之前不会丢弃。因此,“yy”将导致读取两个“y”字符,每次调用一个,因为一次只消耗一个字符。递归的可怕用法。使用一个简单的do-while循环。“我做错了什么”-您似乎在假设
scanf_s(“%c”,&answer,1)stdin
时,code>会神奇地清除所有字符,包括空格和非空格,并保存第一个字符。它不是这样做的。如果您输入“abc”并提取“a”,输入流中仍有“bc”,您的循环每次迭代都会愉快地使用一个。首先,使用
scanf
,scanf
意味着“读取下一个可用字符”,而不是“等待输入”(粗略地说)