循环显示菜单永远不会结束

时间:2014-03-22 16:51:29

标签: c while-loop

我试图在C中写一个简单的菜单。

这是我建议的代码:

while (end == 0) {

    printf("Main menu\n");
    printf("=========\n");
    printf("1) Option 1.\n");
    printf("2) Option 2.\n");
    printf("3) Option 3.\n");
    printf("4) Option 4.\n");
    printf("0) Exit");
    printf("\n");
    printf("Choose an option: ");
    fgets(&menu_option,1,stdin);

    switch (menu_option) {
        case '0': end = 1; break;
        case '1': option1(); break;
        case '2': option2(); break;
        case '3': option3(); break;
        case '4': option4();
    }

}

但是,执行此代码时,循环永远不会结束。

出了什么问题?

谢谢。

编辑:当我说'#34;循环永远不会结束"时,我想说我不能写任何选项,因为菜单一次又一次出现。

4 个答案:

答案 0 :(得分:3)

来自fgets

  

fgets()函数必须从流中读取字节到s指向的数组,直到读取n-1个字节,或者读取a并将其传送到s,或者遇到文件结束条件。然后该字符串以空字节终止。

由于您提供1的长度,n-1将为0,因此您的输入永远不会存储在menu_option中。将其更改为char数组

char menu_option[10];
// ...
fgets(menu_option, sizeof(menu_option), stdin);

switch (menu_option[0]) {
    case '0': end = 1; break;
    case '1': option1(); break;
    case '2': option2(); break;
    case '3': option3(); break;
    case '4': option4();
}

更新

必须使用char数组,因为您需要足够的空间来存储输入。缓冲区的最小大小是两个字符,例如char buf[2],因为fgets存储了您的输入以及终止NUL字符。

循环迭代两次甚至更多次,因为当您输入例如 1返回 1 3 2返回,它将首先返回1,然后返回32,最后返回返回。如果你想读取整行并只使用第一个数字,你的缓冲区必须大于2,例如10甚至256。

答案 1 :(得分:1)

fgets读取字符串而不是字符。声明

fgets(&menu_option,1,stdin);

将字符串存储到menu_option但是要存储字符串,您需要的字符大小至少为2个字节。

char menu_option[2];  
...
fgets(menu_option,2,stdin);   
int c;
while((c = getchar()) != '\n' && c != EOF);  // This will be needed to flush your input buffer 
switch (menu_option[0]) {
        ...
        ...
}

答案 2 :(得分:1)

来自:http://www.cplusplus.com/reference/cstdio/fgets/

  

fgets

     

char * fgets ( char * str, int num, FILE * stream );

     

从流中获取字符串。

     

从流中读取字符并将其存储为C   字符串转换为str,直到读取(num-1)个字符或者a   到达新行或文件结尾,以先发生者为准。

     

换行符使fgets停止读取,但它被认为是a   函数的有效字符并包含在复制到的字符串中   海峡

     

终止空字符会自动附加到   字符复制到str。

由于您为数字指定了1,因此读取了0个字节,并且唯一发生的是附加了终止空字符。结果是一个无限循环,其中没有任何东西被读取。

答案 3 :(得分:1)

由于您在评论中表示不喜欢使用字符串,因此这里的替代实现只需对问题代码进行最少的更改:

while (end == 0) {

    printf("...menu print snipped...\n");

    int ch = getchar();

    switch (ch) {
        case EOF: // end of file or error, fall through to exit option
        case '0': end = 1; break;
        case '1': option1(); break;
        case '2': option2(); break;
        case '3': option3(); break;
        case '4': option4();
        // default: // add error message? 
    }

    // ignore any extra chars in the same line
    while ((ch = getchar() != '\n') {
        // test for end of file and set end to true
        if (ch == EOF) {
            end = 1;
            break;
        }
    }
}

注意额外的循环,它将读取并丢弃输入行的其余部分。没有它,用户可以在一行上输入几个选项​​,这可能是不可取的。另请注意,如果选项函数读取更多用户输入,请考虑如何处理长行。例如,将额外循环移动到切换之前(并添加另一个变量以读取丢弃的字符)。实际上你应该把额外的循环放在它自己的函数discard_until_newline上。