一边留着开关(1)

时间:2019-04-01 20:54:52

标签: c

我暂时需要开关盒。开关中的每种情况都是菜单的一部分,它可以执行某些操作。另外,我还需要处理来自开关的所有输入,因此默认设置不是我的好选择。当用户在CMD中按CTRL + Z时,我需要完全离开,正在执行程序的位置是为了释放内存并退出程序。这段代码只是我的简化版本。请你帮助我好吗?完成任务是我要做的最后一件事。谢谢。

while (1) {
    scanf("%c", &choose);

    switch (choose) {

    case 1:
        //something
        break;
    case 2:
        // something
        break;

    // no default!

    }
}

5 个答案:

答案 0 :(得分:4)

如果用户在Windows上按 Ctrl + Z ,您的程序会将其视为输入文件(stdin)的结尾。当scanf尝试从stdin读取字节时,它将失败并返回-1EOF),而通常的返回值为1(即读取的项目数)

因此您可以使用以下代码:

while (scanf("%c", &choose) == 1)
{
    switch (choose) {

    case 1:
        //something
        break;
    case 2:
        // something
        break;

    // no default!

    }
}

我将scanf的返回值放入while的条件中。当scanf再也无法从stdin读取字节时,循环将终止。

答案 1 :(得分:4)

您在处理Control-Z时遇到的问题不是离开switch语句,而是离开while语句。

在Windows系统上,当用户在输入行的开头按Ctrl-Z时,软件的行为类似于文件结尾。值得注意的是,执行scanf("%c", &choose);时,将没有任何输入可供读取,因此choose中将不会存储任何内容。相反,scanf将返回EOF,以指示可能与"%c"不匹配(因为没有可用的输入)。但是,您的代码不会测试scanf的返回值,因此它将看不到。解决此问题的一种方法是:

while (1)
{
    int n = scanf("%c", choose);
    if (n != 1) // Did scanf match %c and store something in choose?
        break; // No, so break out of the while loop.
    switch (choose)
    …
}

然后就是switch语句中应包含的内容。您说您“需要处理来自开关的所有输入。” char通常具有256个可能的值。因此,除非在case中有256个switch标签,否则您不会处理switch语句中的所有输入。您应该有一个default标签。

如果switch内部的任何情况都需要引起执行而离开while语句,则可以采用各种方式来安排它。一种方法是使用变量来表明:

while (1)
{
    int n = scanf("%c", choose);
    if (n != 1) // Did scanf match %c and store something in choose?
        break; // No, so break out of the while loop.

    int LeaveWhile = 0;
    switch (choose)
    {
        case 'A':
            // Code to handle A input.
            break;
        case 'B':
            …
        case something:  // Some case where we want to end the loop.
            LeaveWhile = 1; // Indicate end of loop.
            break;
        …
        default:
            // Code to handle remaining values.
            break;
    }

    // If it is time to leave the while loop, break out of it.
    if (LeaveWhile)
        break;
}

答案 2 :(得分:1)

在描述如何处理C中过度使用“ break”关键字的问题之前,您可能会遇到另一个需要提及的问题。

control-C control-Z 的行为随操作系统和TTY(控制台)设置的不同而不同。

具有默认TTY设置的

Linux将使用 control-C 引起中断,如果不处理,则会终止程序。 control-Z 将暂停程序。默认情况下,两种情况都不会将字符传递给程序,因此scanf不能读取该字符,并且switch语句也不会分派该字符。

默认情况下,Windows也将使用 control-C 中断。

之所以提到这一点,是因为您依赖于在输入解析中读取控制字符。如果您没有想要的行为,请考虑查看TTY设置。

关于从交换机内部退出“ while(1)”,标准方法是将循环从“ while(1){}”更改为“ int looping = 1; while(looping){}”),并将while循环体内的循环设置为0。

在某些情况下,我会(在孩子看完的时候遮住他们的眼睛)在身体停下后转到标签上。我显眼地显示goto标签,并将其缩进到while循环主体水平之外。

有时中断条件会更自然,有时goto会更清晰。如果您不希望在美学上优先于另一种,则可能会默认使用中断条件,而不是转到条件。

答案 3 :(得分:0)

在循环的顶部添加一个标志,该标志在您要中断时设置,然后在switch之后执行:

while (1) {
    int breakout = 0;

    scanf("%c", &choose);
    switch (choose) {
    case 1:
        //something
        break;
    case 2:
        // something else
        // exit the loop in this case
        breakout = 1;
        break;
    }
    if (breakout) break;
}

答案 4 :(得分:0)

您还有*do - while*循环。

bool continueLoop = true;

do
{
    switch(something)
    {
        case smth1:
            /* ... */
            break
        case smth2:
            /* ... */
            continueLoop = false;   //whis will exit the loop
            break;
        default
            /* ... */
             break;
    }
}while(continueLoop)