Search code examples
arrayscstack

Failing to construct a stack using array in C


Now I have an input consists of a random string with '(' and ')'. I want to push these parentheses into a stack called "balance". But after I input, the program would terminate, and there was nothing in the stack. How can I fix this?

Here's my code:

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

#define STACKSIZE 1000

struct stack  
{
    int top;
    char items[STACKSIZE];
};

void push(struct stack *pb, char x)
{
    if(pb->top==STACKSIZE)
        printf("The stack is full\n");
    else
        pb->items[pb->top++]=x;
}


int main()
{
    while(1)
    {
        struct stack balance;     //the stack called "balance"
        struct stack *b;          //the pointer of stack
        char line[STACKSIZE];     //input
        scanf("%s", line);

        if(!strcmp(line, "-1"))   //program stops when only "-1"
            break;

        b->top=0;                 //initializing top value

        for(int i=0;i<STACKSIZE-1;i++)        
        {
            if(line[i]=='(' || line[i]==')')      //push '(' and ')' in the input to the stack
                push(b, line[i]);
        }
        printf("test");           //can't reach this line
        printf("%s\n", b->items);

    }

    return 0;
}

Solution

  • For some reason, you're using b as a pointer to the stack, instead of &balance itself. This is not wrong, but you must initialize b so it really points to the struct. So, instead of:

    struct stack *b;
    

    You should have:

    struct stack *b = &balance;
    

    Another potential problem is that you're reading until i reaches STACKSIZE. This is wrong, since you don't know whether the input is going to reach that length, and if it does not, then you're reading ahead of the end of line.

    So, instead of:

    for(int i=0;i<STACKSIZE-1;i++)        
    {
    

    You should have:

    for(int i=0;line[i] != '\0';i++)        
    {
    

    BTW, you don't need to define ("redefine for each iteration"), all your locals inside the loop. That's is actually not going to happen, since the optimizer will move them out, but anyway.

    Talking of potential problems, it is always a bad idea to have and infinite loop. Define exactly what is the exit condition, and you'll be in the safe side. You can even define something exceptional to happen and call break in that case, but not as the common rule.

    You're reading input, and in this case something really common is the read-ahead technique.

    int input_status = scanf("%s", line);
        
    while(input_status != EOF
       && strcmp(line, "-1"))
    {
        // more things...
    
        input_status = scanf("%s", line);
    }
    

    This way, each time you're testing the exit condition, you've just read and check whether the end condition ("-1" at input) or there is simply not more input (scanf returns EOF).

    Here comes the complete code:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define STACKSIZE 1000
    
    struct stack  
    {
        int top;
        char items[STACKSIZE];
    };
    
    void push(struct stack *pb, char x)
    {
        if(pb->top==STACKSIZE)
            printf("The stack is full\n");
        else
            pb->items[pb->top++]=x;
    }
    
    
    int main()
    {
        struct stack balance;     //the stack called "balance"
        struct stack *b = &balance;          //the pointer of stack
        char line[STACKSIZE];     //input
        int input_status = scanf("%s", line);
            
        while(input_status != EOF
           && strcmp(line, "-1"))
        {
            b->top=0;                 //initializing top value
    
            for(int i=0;line[i] != '\0';i++)        
            {
                if(line[i]=='(' || line[i]==')')      //push '(' and ')' in the input to the stack
                    push(b, line[i]);
            }
            printf("test");           //can't reach this line
            printf("%s\n", b->items);
    
            input_status = scanf("%s", line);
        }
    
        return 0;
    }