通过推送和弹出对scanf的不同期望

时间:2016-08-21 19:23:42

标签: c stack queue push scanf

在C中编写该程序。使用两个堆栈在队列中实现(CTCI中的问题3.5)。

我想允许用户输入“push {integer}”或“pop”。我正在使用scanf("%s %d", op, &data);

然而,这导致程序中的行为不一致,其中用户输入“push {integer}”工作正常,但是用户输入“pop”导致程序执行延迟。似乎scanf("%s %d", op, &data);等待一些输入放入&数据,但我希望它只接受“pop”而没有任何数据。

代码:

#include "stdio.h"
#include "stdlib.h"
#include "../Chapter-2/linkedlist.h"
#include "string.h"

int main(int argc, char *argv[])
{
    char op[10];
    int data;
    struct node *pushStack = NULL;
    struct node *popStack = NULL;

    printf("Usage: \"push\" some_int ||OR|| \"pop\"\n");
    while(1)
    {
        scanf("%s %d", op, &data);
        if(strncmp(op, "push", 4) == 0)
        {
            if(pushStack == NULL)
            {
                if(popStack != NULL) //we were popping from the "queue" so we need to switch to pushing mode
                {
                    while(popStack != NULL) //transfer all from popstack to pushstack
                    {
                        push(&pushStack, pop(&popStack));
                    }
                }
            }
            push(&pushStack, data);
        } else if(strncmp(op, "pop", 3) == 0)
        {
            if(popStack == NULL)
            {
                if(pushStack != NULL) //we were pushing to "queue" so we need to switch to pop mode
                {
                    while(pushStack != NULL) // transfer all from pushStack to popStack
                    {
                        push(&popStack, pop(&pushStack));
                    }
                }
            }
            if(popStack == NULL) //could still be null if there was nothing to transfer from pushstack
                printf("Queue is empty. You have nothing to pop.\n");
            else
                printf("Popped queue: %d\n", pop(&popStack));
        } else {
            printf("Invalid usage.\n");
            printf("Usage: \"push\" some_int ||OR|| \"pop\"\n");
        }
    }
    return 0;
}

1 个答案:

答案 0 :(得分:2)

您可以尝试根据命令将scanf拆分为两个调用。类似的东西:

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

int main(int argc, char *argv[])
{
    char op[10];
    int data;
    int t = 3;
    int res;

    printf("Usage: \"push\" some_int ||OR|| \"pop\"\n");
    while(t)
    {
        res = scanf("%9s", op);    // Read the command
        if (res == EOF) exit(1);

        if(strncmp(op, "push", 4) == 0)
        {
            do
            {
                res = scanf("%d", &data);  // Read data only when command is push
                if (res == EOF) exit(1);
                if (res != 1) 
                    while ( (res = getchar()) != '\n' && res != EOF ); // Flush stdin
             } while (res != 1);

             printf("%s %d\n", op, data);
        } 
        else if(strncmp(op, "pop", 3) == 0)
        {
            printf("%s\n", op);
        }
        else 
        {
            printf("Invalid usage.\n");
            printf("Usage: \"push\" some_int ||OR|| \"pop\"\n");
        }
        --t;
    }
    return 0;
}
  

输入

push 7
pop
push 42
  

输出

Usage: "push" some_int ||OR|| "pop"
push 7
pop
push 42

顺便说一句:

  

始终检查scanf的返回值

     

永远不要做scanf(%s ....

作为scanf的替代方案,您可以使用fgets。类似的东西:

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

int main(int argc, char *argv[])
{
    char op[10];
    int data;
    int t = 3;

    printf("Usage: \"push\" some_int ||OR|| \"pop\"\n");
    while(t)
    {
        if (fgets(op, 10, stdin) == NULL) exit(1);

        if(sscanf(op, "push %d", &data) == 1)
        {
            printf("push %d\n", data);
        }
        else if(strncmp(op, "pop", 3) == 0)
        {
            printf("pop\n");
        }
        else
        {
            printf("Invalid usage.\n");
            printf("Usage: \"push\" some_int ||OR|| \"pop\"\n");
        }
        --t;
    }
    return 0;
}