【问题标题】:logical error in do-while loop during implementation of data structure "stack"在实现数据结构“堆栈”期间执行循环中的逻辑错误
【发布时间】:2019-10-02 12:49:02
【问题描述】:

我的老师给了我一道作业题,我们必须将push 和pop 元素放在一个堆栈中。

输入应为:-

  1. 输入的第一行必须包含 no。堆栈中的元素。

  2. 输入的第二行必须包含用户(即)选择是 PUSH(即输入'1')还是 POP 元素(即输入 '2')。

  3. 如果选择了 PUSH 操作作为用户的选择;那么输入的第三行必须包含要压入堆栈的元素。

  4. 如果用户希望继续这些操作,下一行输入必须包含'y' 或'n' 作为回复。

测试用例 1

输入

3//(capacity of stack)

1 //(selecting PUSH OR POP)

6//(entering the element which is to entered)

是//(to continue or not continue)

1 //(selecting PUSH OR POP)

4//(entering the element which is to entered)

是//(to continue or not continue)

1 //(selecting PUSH OR POP)

7//(entering the element which is to entered)

是//(to continue or not continue)

2//(selecting PUSH OR POP)

n//(to continue or not continue)

输出

deleted element is

7 4 6

针对上述问题我写了如下代码:-

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

struct Stack
{
    int capacity;
    int top;
    int *array;
};

void push(struct Stack *stack, int a) //function to PUSH a character in the stack.
{
    stack->array[++stack->top] = a;
}

int pop(struct Stack *stack) //function to POP a character in the stack.
{
    return stack->array[stack->top--];
}

int main(void)
{
    struct Stack obj;
    obj.top = -1;

    printf("Enter the capacity of stack\n");
    scanf("%d", &obj.capacity); //Inputting the capacity of the stack.

    obj.array = calloc(obj.capacity, sizeof(int));

    int operation;
    int element;
    char continuation;

    do
    {
        printf("\nEnter 1 if you want to PUSH or 2 for POP\n");
        scanf("%d", &operation);

        printf("\nEnter the element which is to be pushed\n");
        scanf("%d", &element);

        scanf("%*c"); //To ignore any newline in stdin buffer.
        printf("\nEnter 'y' if you want to continue else enter 'n'\n");
        scanf("[a-z]%c", &continuation);

        if(operation == 1)
        {
            if(obj.top < obj.capacity)
            {
                push(&obj, element);
            }
            else
            {
                printf("Error\n");
                return EXIT_FAILURE;
            }
        }

        else if(operation == 2)
        {
            printf("deleted element is\n");
            while(obj.top != -1) //will POP all elements on the stack and print it.
            {
                printf("%d", pop(&obj));
                if(obj.top != 0)
                {
                    printf(" ");
                }
            }
        }

        else
        {
            printf("Wrong operation specified\n");
            return EXIT_FAILURE;
        }
    } while(continuation == 'y');

    return 0;
}

我在上面代码中遇到的问题是输入以下内容后:-

3

1

6

是的

程序关闭(即退出do-while 循环)。但是,当我在代码中更改以下行时:-

char continuation;

到

char continuation = 'y';

在我输入以下内容之前它工作正常:-

3

1

6

是的

1

4

是的

1

7

是的

然后给我一个突然的输出:-

Error

然后退出程序。

我的问题是:-

当我只写char continuation;时,为什么我的代码在第一种情况下不起作用?

当我将char continuation; 更改为char continuation = 'y'; 时,第二种情况下的“逻辑错误”是什么?

【问题讨论】:

  • 我认为"[a-z]%c" 想要扫描文字“[a-z]”,然后是一个字符。 " %c" 格式(带有前导空格)会跳过包括换行符在内的空格,然后尝试读取非空格字符。我说“尝试”,因为扫描可能会失败,scanf 的返回值会告诉你。在我看来,像你这样的交互式输入是最好的,例如fgets,然后解析。 sscanf 函数从字符串中获取输入。
  • 错误消息似乎链接到案例操作 == 1 和 obj.top >= obj.capacity(您的代码)。您应该打印扫描的值或使用调试器来查看您到达此分支的原因。
  • @Nico238 但obj.top 必须小于obj.capacity
  • @MOehm 所以我吃\n 的方法完全错误?
  • 此外,请尽量避免像您那样混合(交错)。请求操作后,先执行操作,然后询问是否继续。因此,与操作相关的错误会突然打印出来,而不是在请求是否继续之后。

标签: c loops


【解决方案1】:

我可以通过删除"[a-z]%c" 并将其替换为" %c" 来解决我的问题。

这是我的新(正确)代码。

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

struct Stack
{
    int capacity;
    int top;
    int *array;
};

void push(struct Stack *stack, int a) //function to PUSH a character in the stack.
{
    stack->array[++stack->top] = a;
}

int pop(struct Stack *stack) //function to POP a character in the stack.
{
    return stack->array[stack->top--];
}

int main(void)
{
    struct Stack obj;
    obj.top = -1;

    printf("Enter the capacity of stack\n");
    scanf("%d", &obj.capacity); //Inputting the capacity of the stack.

    obj.array = calloc(obj.capacity, sizeof(int));

    int operation;
    int element;
    char continuation;

    do
    {
        printf("\nEnter 1 if you want to PUSH or 2 for POP\n");
        scanf("%d", &operation);

        if(operation == 1)
        {
            printf("\nEnter the element which is to be pushed\n");
            scanf("%d", &element);

            if(obj.top < obj.capacity)
            {
                push(&obj, element);
            }
            else
            {
                printf("Error\n");
                return EXIT_FAILURE;
            }
        }

        else if(operation == 2)
        {
            printf("deleted element is\n");
            while(obj.top != -1) //will POP all elements on the stack and print it.
            {
                printf("%d", pop(&obj));
                if(obj.top != 0)
                {
                    printf(" ");
                }
            }
        }

        else
        {
            printf("Wrong operation specified\n");
            return EXIT_FAILURE;
        }

        scanf("%*c"); //To ignore any newline in stdin buffer.
        printf("\nEnter 'y' if you want to continue else enter 'n'\n");
        scanf(" %c", &continuation);

    } while(continuation == 'y');

    return 0;
}

注意:- 我也避免按照 cmets 中的建议交错 printf。

但是我仍然无法理解为什么我以前的代码不起作用。

附言

我终于弄错了,应该是"%[a-z]c",而不是"[a-z]%c"。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 2013-01-23
    • 1970-01-01
    相关资源
    最近更新 更多