C-do/while循环和开关(int)。键入字符值会导致inf.loop

C-do/while循环和开关(int)。键入字符值会导致inf.loop,c,C,有人能告诉我怎么做吗?现在我有一个do/while循环,里面有一个开关。开关由int选项处理,scanf为“%d”。但如果我写一个和数字不同的字符,比如a,b,c。。。它进入无限循环。将int更改为char并将%d更改为%c可以工作,但如果输入了错误,菜单将重复x2并变得混乱。对不起,英语不好:) 带int: int main() { int choice; do{ menu(); scanf("%d", &choice); switch

有人能告诉我怎么做吗?现在我有一个do/while循环,里面有一个开关。开关由int选项处理,scanf为“%d”。但如果我写一个和数字不同的字符,比如a,b,c。。。它进入无限循环。将int更改为char并将%d更改为%c可以工作,但如果输入了错误,菜单将重复x2并变得混乱。对不起,英语不好:) 带int:

int main() {
 int choice;
    do{
        menu();
        scanf("%d", &choice);
    switch(choice) {
        case 1:
            // 1-vo poduslovie
            ReadSave();
            break;
        case 2:
            // 2-ro poduslovie
            ShowResult();
            break;
        case 3:
            // 3-to poduslovie
            SavetoScreen();
            break;
        case 4:
            // 4-to poduslovie
            PrinttoScreen();
            break;
        case 5: // exit
            return 0;
        default:
            printf("Wrong choice.\n");
    }
}while(choice!=5);
使用char:

int main() {
 char choice;
    do{
        menu();
        scanf("%c", &choice);
    switch(choice) {
        case '1':
            // 1-vo poduslovie
            ReadSave();
            break;
        case '2':
            // 2-ro poduslovie
            ShowResult();
            break;
        case '3':
            // 3-to poduslovie
            SavetoScreen();
            break;
        case '4':
            // 4-to poduslovie
            PrinttoScreen();
            break;
        case '5': // exit
            return 0;
        default:
            printf("Wrong choice.\n");
    }
}while(choice!='5');

使用
%d
,如果输入非整数,
scanf
将忽略它,并且不会将其从输入缓冲区中删除。每次通过循环时,非字符仍然存在,因此
scanf
忽略它,
choice
从不更改,循环也从不退出

Edit您可以通过检查
scanf
中的返回值来判断是否发生了这种情况。如果返回值为
1
,scanf将匹配
%d
,这是格式字符串中的单个(
1
)项。如果返回值为
0
scanf
无法匹配
%d
,例如,由于存在字符数据。我想这就是代码中发生的情况

中详细讨论了如何在
scanf
之前清除输入。但是,如a中所述,您最好使用
fgets
获得一整行,然后使用
sscanf
从得到的字符串中提取整数(如果有的话)。参见,例如

资料来源:

  • 报告说:

    阅读字符停止。。。当找到不匹配的字符时

    因此,非数字保留在输入流中,例如,供将来的
    scanf
    尝试匹配

我最后用了这个:

int choice;
 char string[20];
    do{
        menu();
        fgets(string, sizeof(string), stdin);
        sscanf(string, "%d", &choice);
     switch(choice) { /*menu......*/}

完整代码:(尚未在那里编辑)

为每种情况显示一个示例输入序列。另外,修复您的括号和缩进。
scanf(“%c”,&choice)==>
scanf(“%c”,选择(&c))请注意额外的空间
%c
格式读取下一个字符,而其他格式过滤掉空白。更好的是,使用
fgets
并应用
sscanf
并始终检查其返回值。
scanf
family的返回值是多少?阅读手册页。使用
fgets
更容易转储字符串并重试,而不是尝试清除坏输入,否则将继续阻塞缓冲区。您应该始终检查
scanf
中的返回值,以确保它读取了您期望的项目数,并且没有失败或达到eof。好的,谢谢您的回答。人员:)将查看适合我使用的选项。因为我是一个完全的初学者,也许我会通过fgets成功。这是完整的代码(我也必须改变这一点,因为我不止一次使用了scanf。@MESA很高兴听到这一点!如果你觉得我的答案有帮助,请点击向上的三角形将其标记为这样好吗?---另外,欢迎访问该网站!查看更多信息,以帮助你最有效地参与堆栈溢出。使用stackoverflow作为everyone否则你应该投票给告诉你如何做的人--不要发布新答案。这不是表格。请阅读常见问题解答以了解更多有关如何工作的信息。你的“解决方案”包含未定义的行为。您必须检查所调用函数的返回值。这是一个仅限代码的答案,不能解释它解决问题的原因。它的缺点是在使用下一行中的
string
choice
之前,不检查
fgets()
sscanf()的返回值。对不起,各位:)。现在将阅读有关如何使用stackoverflow的规则和常见问题解答。