使用scanf进入无限循环

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

所以我有一段这样的代码(我只想说这是C89的):

void inputChoice(int* choicePtr)
{
    int choice;
    printf(BLUE "\nINPUT: " RESET);                     /* Print input using the ansi colour code for Blue. */
    scanf("%d", &choice);                               /* Parse the choice. */

    while ((choice < 1) && (choice > 5))                /* Loop until choice is one of the menu options. */
    {
        /* Request for a valid menu option, printing this using the ansi colour code for Red, then resetting back to the default colour. */
        printf(RED "\nMenu Selection must be between (1 and 5) inclusive. \nPlease Re-enter. \n" RESET);
        scanf("%d", &choice);                           /* Parse the choice. */
    }
    *choicePtr = choice;                                /* Set the choice pointer to the valid choice after validation. */
}

哪一个得到了选择。对于整数来说,这很好用。但是如果有人输入其他的东西,例如一个字符。它就会无限循环。我想以某种方式检查是否输入了一个字符。

我试过的一种方法是添加这个来检查是否有字符被输入,因为如果没有正确扫描,整数会是0。

就像下面这样,但这也不行。

scanf("%d", &choice);

while (choice == 0)
{
    printf("Invalid Choice Re-enter.");
    scanf("%d", &choice);
}

c validation user-input c89
1个回答
2
投票

表达式

while ((choice < 1) && (choice > 5))  

永远不会是真的,因为 choice 大不了 5 且小于 1.

你需要。

while (choice < 1 || choice > 5) 

scanf 将会尝试解析缓冲区中是否有任何东西,但无法解析,它会继续尝试,导致无限循环,因为不管缓冲区中的东西是什么,都会留在那里,直到它被成功解析。

因为 scanf 将返回 0 如果没有参数被解析,你可以使用这些信息来清除缓冲区,消除导致无限循环的原因。

int choice = 0;
int c; 
int scanned;
//...
if ((scanned = scanf("%d", &choice)) == EOF){ //check for EOF return
    puts("Unexpected error.");       
    //error treatment is upt to you, I would avoid the loop
    *choicePtr = scanned;
    return;
}
if (scanned == 0) {
    while ((c = fgetc(stdin)) != '\n' && c != EOF){}
}

在两种情况下 scanfs.

现场演示


1
投票

考虑到评论中的意见,以下是一个修改版本。

/* reading an input choice between 1 and 5 or -1 on error */
void inputChoice(int *choicePtr) {
    int choice;

    printf(BLUE "\nINPUT: " RESET);       /* Print input using the ansi colour code for Blue. */

    for (;;) {
        int res = scanf("%d", &choice);   /* Parse the choice. */
        if (res == EOF) {
            printf(RED "unexpected end of file\n" RESET);
            choice = -1;
            break;
        }
        if (res == 0) {
            int c;
            while ((c = getchar()) != EOF && c != '\n')
                continue;
            printf(RED "invalid entry\n" "Please Re-enter.\n" RESET);
            continue;
        }
        if (choice >= 1 && choice <= 5) {
            break;
        }
        /* Loop until choice is one of the menu options. */
        /* Request for a valid menu option, printing this using the ansi 
           colour code for Red, then resetting back to the default colour. */
        printf(RED "\nMenu Selection must be between (1 and 5) inclusive.\n"
               "Please Re-enter.\n" RESET);
    }
    /* Set the choice pointer to the valid choice after validation. */
    *choicePtr = choice;
}
© www.soinside.com 2019 - 2024. All rights reserved.