[C switch语句错误常规情况和默认命中

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

在接触Java之后,我目前正在用C编写我的第一个程序,该程序的目的是模拟一个可容纳10个整数的堆栈。用户可以要求按下('u'),pop('o'),exit('x')或更改输出格式。我如何处理输出存在一个错误,但是以后可以解决。引起关注的主要原因是在运行程序时得到以下输出:

欢迎使用堆栈程序。

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

如您所见,该程序允许我将项目推入堆栈并存储它们(弹出也可以),但是每次提示用户输入新选项时,在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;
    }
}

提前感谢您的时间!

c debugging stack switch-statement
4个回答
4
投票

main()中更改:

scanf ("%c", &currentOption);

to

scanf (" %c", &currentOption);

原因是在第一个输入之后输入的流浪换行符被紧随其后的scanf()立即消耗掉。要解决此问题,请在转换说明符之前使用空格。前缀为%c的空格告诉scanf()跳过前一个杂散字符,仅使用此后输入的字符。


3
投票

主要问题是:

用户首先输入字符,然后按回车键来输入字符。

那个键(换行符)仍然在下一个循环顶部的缓冲区中,所读取的内容也是如此。

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

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

scanf (" %c", &currentOption);

注意格式字符串中的前导空格吗?格式字符串中的空格会导致在输入处的空白处被占用。

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


2
投票

我认为您的switch语句没有任何问题,而是您要获取的位置

char option

在我看来,您正在执行类似操作

scanf("%c", &option);
processOption(option);

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

scanf(" %c", &option);

这会导致scanf跳过所有前导空格,包括换行符。对于scanf(“%d”,int),这不是必需的,因为空格显然对数字值无效,但might对字符有效。


0
投票

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

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