Search code examples
cwhile-loopstackpalindromegetchar

Pushing a word to a stack and checking it for Palindrome


Our teacher gave us homework to check for palindrome of a word using data structure "Stack".

Below is the code which I have written for the following problem: -

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

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

void push(struct Stack stack, char a) //Push function.
{
    stack.array[++stack.top] = a; //Helps to push charater to a stack.
}

char pop(struct Stack stack) //Pop function.
{
    return stack.array[stack.top--]; //Helps to pop character from a stack.
}

int main(void)
{
    struct Stack original; //Original stack where the "Original" word will be pushed.
    original.top = -1;
    original.capacity = 10;
    original.array = calloc(original.capacity, sizeof(char));

    struct Stack checker; //Another stack that "Checks" whether the word is palindrome or not.
    checker.top = -1;
    checker.capacity = 10;
    checker.array = calloc(checker.capacity, sizeof(char));

    while(getchar()!='\0') //Getting all the characters from the stdin buffer and pushing it into "Original" stack.
    {
        push(original, getchar());
    }

    while(original.top != -1)
    {
        push(checker,pop(original)); //Popping from "Original" stack and pushing it to "Checker" stack.
    }

    while(checker.top != -1)
    {
        original.top = checker.top;
        if(original.array[original.top] != checker.array[checker.top]) //Checking every character in the stack if it is excatly same or not.
        {
            printf("It is not a palindrome.\n");
            return EXIT_SUCCESS;
        }
        else
        {
            checker.top = checker.top - 1;
        }
    }

    if(checker.top == -1)
    {
        printf("It is a palindrome.\n");
    }

    return 0;
}

Howsoever I am getting problem in the following line: -

while(getchar()!='\0') //Getting all the characters from the stdin buffer and pushing it into "Original" stack.
{
    push(original, getchar());
}

The following loop is running infinitely. My purpose of adding the following line is that I want to add individual characters from stdin buffer and push it in the original stack until it encounters '\0'.

What have I done wrong here? Is it illegal to do it this way?

Addendum: -

Sample Input 1: - civic

Expected Output: - It is a palindrome.

Sample Input 2: - madama

Expected Output: - It is not a palindrome.

P.S.

The following code: -

while(getchar()!='\0') //Getting all the characters from the stdin buffer and pushing it into "Original" stack.
{
    push(original, getchar());
}

has now been replaced with: -

int c;
int i = 0;

while ( i < original.capacity && ( c = getchar() ) != EOF && c != '\n' )
{
    push(original, c );
    ++i;
}

And is now working perfectly, howsoever now, for every word, my code is giving the output: -

It is a palindrome.

Where have I applied the concept of stack incorrectly?


Solution

  • This loop

    while(getchar()!='\0') //Getting all the characters from the stdin buffer and pushing it into "Original" stack.
    {
        push(original, getchar());
    }
    

    is in any case wrong because it reads characters twice: in the condition of the loop and within the body of the loop.

    And you have explicitly to enter 0 using for example keypad.

    What you need is the following

    int c;
    int i = 0;
    
    while ( i < original.capacity && ( c = getchar() ) != EOF && c != '\n' )
    {
        push(original, c );
        ++i;
    } 
    

    Also there is one more problem. These functions deal with a copy of the passed arguments.

    void push(struct Stack stack, char a) //Push function.
    {
        stack.array[++stack.top] = a; //Helps to push charater to a stack.
    }
    
    char pop(struct Stack stack) //Pop function.
    {
        return stack.array[stack.top--]; //Helps to pop character from a stack.
    }
    

    You have to declare them like

    void push(struct Stack *stack, char a) //Push function.
    {
        stack-?array[++stack->top] = a; //Helps to push charater to a stack.
    }
    
    char pop(struct Stack *stack) //Pop function.
    {
        return stack->array[stack->top--]; //Helps to pop character from a stack.
    }
    

    That is to pass the original stack by reference through pointer.

    And call these functions as for example

    push( &original, c );
    

    Otherwise the data member top will not be changed.

    Here is your updated program

    # include <stdio.h>
    # include <stdlib.h>
    
    struct Stack
    {
        int top;
        int capacity;
        char *array;
    };
    
    void push(struct Stack *stack, char a) //Push function.
    {
        stack->array[++stack->top] = a; //Helps to push charater to a stack.
    }
    
    char pop(struct Stack *stack) //Pop function.
    {
        return stack->array[stack->top--]; //Helps to pop character from a stack.
    }
    
    int main(void)
    {
        struct Stack original; //Original stack where the "Original" word will be pushed.
        original.top = -1;
        original.capacity = 10;
        original.array = calloc(original.capacity, sizeof(char));
    
        struct Stack checker; //Another stack that "Checks" whether the word is palindrome or not.
        checker.top = -1;
        checker.capacity = 10;
        checker.array = calloc(checker.capacity, sizeof(char));
    
        int c;
        int i = 0;
    
        while ( i < original.capacity && ( c = getchar() ) != EOF && c != '\n' )
        {
            push( &original, c );
            ++i;
        }
    
        while(original.top != -1)
        {
            push(&checker,pop(&original)); //Popping from "Original" stack and pushing it to "Checker" stack.
        }
    
        while(checker.top != -1)
        {
            original.top = checker.top;
            if(original.array[original.top] != checker.array[checker.top]) //Checking every character in the stack if it is excatly same or not.
            {
                printf("It is not a palindrome.\n");
                return EXIT_SUCCESS;
            }
            else
            {
                checker.top = checker.top - 1;
            }
        }
    
        if(checker.top == -1)
        {
            printf("It is a palindrome.\n");
        }
    
        return 0;
    }
    

    Take into account that these headers

    #include <string.h>
    #include <stdbool.h>
    

    are redundant.