【问题标题】:C - do/while loop and switch(int). Typing a char value causes inf. loopC - do/while 循环和 switch(int)。键入 char 值会导致 inf。环形
【发布时间】:2016-12-27 17:17:54
【问题描述】:

有人可以启发如何进行这项工作吗?所以现在我有一个 do/while 循环,里面有一个开关。开关由 int 选择处理,scanf 为“%d”。但是,如果我写一个与数字不同的字符符号,例如 a、b、c ......它会进入无限循环。将 int 更改为 char 并将 %d 更改为 %c 有效,但如果输入错误,菜单会重复 x2 并且变得混乱。对不起英语不好:) 带整数:

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

带字符:

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');

【问题讨论】:

  • 显示每个案例的示例输入序列。
  • 另外,修正括号和缩进。
  • scanf("%c", &choice); ==> scanf(" %c", &choice); 请注意多余的空间。 %c 格式否则会读取 下一个字符,而其他格式会过滤掉空格。
  • 更好的是,使用fgets 并应用sscanf始终检查其返回值。 scanffamily 的返回值是多少?阅读手册页。使用fgets,转储字符串并重试比尝试清除错误输入更容易,否则会继续阻塞缓冲区。
  • 您应该始终检查来自scanf 的返回值,以确保它读取了您预期的项目数并且没有失败或命中eof。

标签: c


【解决方案1】:

对于%d,如果输入一个非整数,scanf 会忽略它并且不会将其从输入缓冲区中删除。 每次循环时,非字符仍然是在那里,所以scanf 忽略它,choice 永远不会改变,循环永远不会退出。

编辑您可以通过检查来自scanf 的返回值来判断这是否正在发生。如果返回值为1,则scanf 匹配%d,这是格式字符串中的单个(1) 项。如果返回值为0,则scanf 无法匹配%d,例如,因为存在字符数据。我想这就是你的代码中发生的事情。

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

来源:

  • scanf manpage 说:

    字符读取停止...当发现不匹配字符时

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

  • fgets manpage

【讨论】:

  • 好的,谢谢大家的回答 :) 看看选择什么适合我的使用。因为我是一个完全的初学者,也许我会用 fgets 做到这一点。这是完整的代码(我也必须更改它,因为我不止一次使用 scanf。drive.google.com/file/d/0B5H_NO3oeuLZNjJ2bjdzcWJsNzQ/…
  • @MESA 很高兴听到这个消息!如果您发现我的回答有帮助,请您点击向上的三角形将其标记为这样吗? --- 另外,欢迎光临本站!查看tour 了解更多信息,以帮助您最有效地参与 Stack Overflow。
【解决方案2】:

我用这个结束了:

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

完整的代码:(尚未编辑)。 https://drive.google.com/file/d/0B5H_NO3oeuLZNjJ2bjdzcWJsNzQ/view

【讨论】:

  • 要像其他人一样使用stackoverflow,您应该投票支持告诉您如何执行此操作的人——而不是发布新答案。这不是形式。请阅读常见问题解答,了解有关 SO 工作原理的更多信息。
  • 您的“解决方案”包含未定义的行为。您必须检查您调用的函数的返回值。
  • 这是一个纯代码答案,并没有解释为什么它可以解决问题。它的弱点是在下一行使用stringchoice 之前不检查fgets()sscanf() 的返回值。
  • 对不起各位:)。现在将阅读有关如何使用 stackoverflow 的规则和常见问题解答。
猜你喜欢
  • 1970-01-01
  • 2020-08-01
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 2018-05-09
  • 2015-07-03
  • 1970-01-01
相关资源
最近更新 更多