C switch语句bug常规情况和默认命中

时间:2015-05-13 04:28:29

标签: c debugging stack switch-statement

我目前正在用C语言编写我的第一个程序,这个程序的目的是模拟一个包含10个整数的堆栈。用户可以要求推送(' u'),弹出(' o'),退出(' x')或更改输出格式。我如何做输出有一个错误,但我可以稍后处理。引起关注的主要原因是我在运行程序时得到了这个输出:

欢迎使用堆栈程序。

输入选项:u
什么号码? 1
堆叠:1
输入选项:无效字符。
输入选项:u
什么号码? 2
筹码:1 2
输入选项:无效字符。
输入选项:u
什么号码? 3
筹码:1 2 3
输入选项:无效字符。
输入选项:

正如您所看到的,该程序允许我将项目推送到堆栈并存储它们(pop也可以),但每次提示用户输入新选项时,我的switch语句中都会出现无效字符大小写并创建一个错误的多余行。我理解更多的程序上下文可能是必要的,但是我的switch语句有什么明显的错误吗?

#include <stdio.h>
#include <stdlib.h>

char currentOption;
int *printMode = 0;

//A program to simulate a stack data type of integers.
int main()
{
    printf("Welcome to the stack program.\n");
    printf("\nEnter option: ");
    scanf ("%c", &currentOption);

    while(currentOption != 'x')
    {
        processOption(currentOption);
        printf("\nEnter option: ");
        scanf ("%c", &currentOption);
    }
    return 0;
}

//interpret the user input character as one of several options
void processOption(char option)
{
    int storedValue;

    switch(option)
    {
        case 'u' : //push to stack
            printf("What number? ");
            scanf ("%d", &storedValue);
            if(push(storedValue) == 1)
            {
                printf("Overflow!!!");
            }
            else
            {
                printf("Stack: ");
                printStack(printMode);
            }
            break;
        case 'o' : //pop, return popped value
            pop(&storedValue);
            if(storedValue == NULL)
            {
                printf("Underflow!!!");
            }
            else
            {
                printf("Popped %d", storedValue);
                printf("\nStack: ");
                printStack(printMode);
            }
            break;
        case 'd' : //change print mode to decimal and print
            printf("\nStack: ");
            *printMode = 0;
            printStack(printMode);
            break;
        case 'h' : //change print mode to hex and print
            printf("\nStack: ");
            *printMode = 1;
            printStack(printMode);
            break;
        case 'c' : //change print mode to char and print
            printf("\nStack: ");
            *printMode = 2;
            printStack(printMode);
            break;
        case 'x' : //change print mode to char and print
            printf("Goodbye!");
            exit(EXIT_SUCCESS);
        default :
            printf("Invalid character." );
            break;
    }
}

提前感谢您的时间!

4 个答案:

答案 0 :(得分:4)

main()更改:

scanf ("%c", &currentOption);

scanf (" %c", &currentOption);

原因是第一次输入后输入的迷路换行符会立即被scanf()消耗。
要解决此问题,请在转换说明符前使用空格。
前缀为%c的空白区域告诉scanf()跳过第一个杂散字符,只消耗之后输入的字符。

答案 1 :(得分:3)

主要问题是:

用户首先键入字符,然后点击“返回”字符来输入字符。键。

该键(换行符)仍在下一个循环顶部的缓冲区中,因此读取的内容。

该换行符是“白色空间”的一部分。定义。

要消耗空白,请像这样写入scanf:

scanf (" %c", &currentOption);

注意格式字符串中的前导空格?格式字符串中的空格会导致在输入中的该点消耗空白区域。

此外,应始终检查scanf()和函数族的返回值,以确保输入/转换操作成功。

答案 2 :(得分:2)

我认为你的switch语句没有任何问题,而是你在哪里获取

char option

我认为你喜欢做

之类的事情
scanf("%c", &option);
processOption(option);

循环。当processOption()返回时,scanf会立即获取当您按Enter键时放入流中的换行符。 \ n,当然,这不是您有效的选择之一。因此,将您的scanf调用更改为

scanf(" %c", &option);

这会导致scanf跳过所有前导空格,包括换行符。 scanf(&#34;%d&#34;,int)不需要这样做,因为空格显然对数值无效,但可能对char有效。

答案 3 :(得分:0)

是的,即使在JAVA扫描仪中,如果您扫描整数类型(如int,double),它将读取直到打到可选符号为止,然后继续直到打到一个数字,然后再继续写数字,然后再进行浮点/双精度运算小数点,直到读取了其他内容,然后将其放回缓冲区(始终有1的空间,请参见man ungetc())。因此,换行符在缓冲区中,等待下一个扫描输入。这是计算机按照您的要求做的经典案例。您可以将文字换行符'\ n'放入格式以使其被scanf吃掉,或者添加某种虚拟读取,或者将一行读入string / String / char []并使用sscanf()/ Scanner进行扫描/ >>!