具有“while”语法的scanf(“%d”,a)绕过scanf

问题描述 投票:1回答:2

如果没有初始化(“mod = 0”),则此代码将进入无限循环。我无法理解为什么这个代码循环,即使我使用了getchar();擦除缓冲区。当我先键入“1”,然后键入“a”时,会出现无限循环。任何人都可以帮我理解这种情况吗?

int main()
{
    srand((unsigned)time(NULL));
    int mod = 0;
    int val = 0;
    do {    
        printf("\t-----------------------------\n");
        printf("\t|%5s %5s %5s %5s|\n", "1.create", "2.modify", "3.print", "4.quit");
        printf("\t|%15s","Input command  : ");
        scanf("%d", &mod);
        printf("\t-----------------------------\n");
        switch (mod){
        case 1:     random();           val++;      break;
        case 2:     if(val != 0) { modify();    break; }
        case 3:     if(val != 0) { print();     break; }
        default:    getchar(); printf("\tUnknown Command!! Retry!! \n");    break;
        }
    } while (mod != 4);
}

我用Visual Studio 2015编译了这段代码。

c switch-statement scanf
2个回答
2
投票

当你输入a时,它是mod的无效输入,因为scanf()期望int%d。所以它没有被读入mod。所以mod留下了在前一次迭代中输入的mod的值。

它进入无限循环的原因是因为scanf()不会丢弃无效输入。因此反复尝试读取a并失败并循环继续。

检查scanf()的返回值并丢弃任何无效的输入。 scanf()对于阅读用户输入而言是非常糟糕的,并且正确处理输入失败通常更难以使用它。

更好的方法是使用fgets()读取行输入,然后使用sscanf()解析它。

do {
    ...

    printf("\t|%15s","Input command  : ");

    fgets(line, sizeof line, stdin);
    char *p = strchr(line, '\n');
    if(p) *p = 0; /* remove tailing newline, if present */
    if( sscanf(line, "%d", &mod) != 1) {
       printf("Invalid input\n");
       continue;
    }

    printf("\t-----------------------------\n");
    ....

   }while (mod != 4);

1
投票

你的代码的问题是,一旦你输入一个有效的菜单选项的数字,变量mod总是等于你第一次输入时输入的相同数字,如果你输入了错误的输入第二次。这种行为来自于这一事实

scanf(%d, &mod);

尝试读取整数,但是当您输入“a”作为第二个选项时,输入无法从标准输入中读取整数。因此,它不会进入switch方法的默认情况,因为变量mod等于您输入的第一个有效输入的输入。

© www.soinside.com 2019 - 2024. All rights reserved.