C - do/while 循环和 switch(int)。输入 char 值会导致 inf。环形

有人可以启发如何进行这项工作吗?所以现在我有一个 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');

最佳答案

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

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

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

来源:

  • scanf manpage说:

    Reading of characters stops ... when a nonmatching character is found

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

  • fgets manpage

https://stackoverflow.com/questions/41349376/

相关文章:

haskell - 如何使 Pipe 与 Haskell 的 Pipe 库并发?

android - 使用 DownloadManager.Request 从 url 下载文件时下载

unity3d - 切换场景时网格会重新加载吗?

cherrypy - 更改 Content-Type 后返回的内容未自动编码

compiler-construction - 这个产生式规则是否左递归?

sprite-kit - SpriteKit : calculate distance betwee

hdf5 - dask 和并行 hdf5 写入

class - 为什么我不能定义 `delete` 方法?

Ansible - 使用用户输入选择变量

apache-spark - 自定义 log4j 类不适用于 spark 2.0 EMR