-4
#include <stdio.h>
#define MAXLEN 100

typedef struct
    {
     char element[MAXLEN];
     int top;
    } stack;

stack init(stack s)
{
     s.top=-1;
     return s;
}

int isEmpty(stack s){
     return(s.top==-1);
}

int isFull(stack s){
    return (s.top==MAXLEN-1);
}

stack push(stack s,char ch){

  if(s.top==MAXLEN-1){
     printf("\n the stack is full\n");
     return s;
  }
  else{
     ++s.top;
     s.element[s.top]=ch;
     return s;
  }  
}

stack pop(stack s){
    if(s.top==-1){
       printf("\n the stack is empty");
       return s;
    }
    else{
       --s.top;
       return s;
    }
}

void top(stack s){
    if(s.top==-1){
        printf("\n empty stack");
    }
    else
        printf("%c",s.element[s.top]);
    }

void print(stack s){
    int i;
    printf(" serial no         character   ");
    for(i=0;i<s.top;++i){
       printf("   %d                %c \n",i,s.element[i]);
    }
}

int main(){

       stack s; 
       s.top=-1; 
       init(s);

       char e; 
       int n,j=1,k;
       while(j==1){

           printf("\n enter your choice 1.push 2.pop 3.top 4.print 5.exit:");
           scanf("%d",&n);

      switch(n)
        {
        case 1:
            printf("\n enter the element to be pushed:  ");
            scanf("%ch",&e);
            s=push(s,e);
            break;
        case 2:
            s=pop(s);
            break;
        case 3:
           top(s);
           break;
        case 4:
          print(s);
          break;
        case 5:
          j=0;
          break;   
        default:      
          printf("\n wrong choice entered enter correct one ");
          break;
         }
    }
}

The error occurs after I compiled and run it and have scanned a character; it goes out of the switch and is not scanning the value of n for consecutive time and is just going into switch with the pre-assigned value and it comes out of switch and asks for n to enter t. In this way I am encountering space as character automatically in the stack elements and the top is getting doubled. Please help me with this. You can once compile it and check for yourself.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278

2 Answers2

1

Change

 scanf("%ch",&e); /* %ch ? */

To

 scanf(" %c",&e); // notice a whitespace in the format string

As scanf("%c",&e); leaves a newline, which is consumed again.

which tells scanf to ignore whitespaces.

OR

if (scanf(" %c",&e) != 1)
        //Print error
Santosh A
  • 5,173
  • 27
  • 37
0

It doesn't take a lot to make the code work sanely. In the fixed code below, I pre-declare the functions because of the compiler options I use. An alternative is to define the functions as static.

#include <stdio.h>
#define MAXLEN 100

typedef struct
{
    char element[MAXLEN];
    int top;
} stack;

int isEmpty(stack s);
int isFull(stack s);
stack init(stack s);
stack pop(stack s);
stack push(stack s, char ch);
void print(stack s);
void top(stack s);

stack init(stack s)
{
    s.top = -1;
    return s;
}

int isEmpty(stack s)
{
    return(s.top == -1);
}

int isFull(stack s)
{
    return(s.top == MAXLEN - 1);
}

stack push(stack s, char ch)
{
    if (s.top == MAXLEN - 1)
    {
        printf("the stack is full\n");
    }
    else
    {
        ++s.top;
        s.element[s.top] = ch;
    }
    return s;
}

stack pop(stack s)
{
    if (s.top == -1)
    {
        printf("the stack is empty\n");
    }
    else
    {
        --s.top;
    }
    return s;
}

void top(stack s)
{
    if (s.top == -1)
        printf("empty stack\n");
    else
        printf("TOS: %c\n", s.element[s.top]);
}

void print(stack s)
{
    int i;
    printf("serial no   character\n");
    for (i = 0; i <= s.top; ++i)
    {
        printf("  %3d       %c\n", i, s.element[i]);
    }
}

int main(void)
{
    stack s;
    s.top = -1;
    init(s);

    char e;
    int n, j = 1;
    while (j == 1)
    {
        printf("\nenter your choice 1.push 2.pop 3.top 4.print 5.exit: ");
        if (scanf("%d", &n) != 1)
        {
            fprintf(stderr, "Failed to read a number.\n");
            return 1;
        }

        switch (n)
        {
        case 1:
            printf("\nenter the element to be pushed: ");
            if (scanf(" %c", &e) != 1)
            {
                fprintf(stderr, "Failed to read a character.\n");
                return 1;
            }
            s = push(s, e);
            break;
        case 2:
            s = pop(s);
            break;
        case 3:
            top(s);
            break;
        case 4:
            print(s);
            break;
        case 5:
            j = 0;
            break;
        default:
            printf("incorrect choice (%d not in range 1-5); enter correct one\n", n);
            break;
        }
    }
    return 0;
}

Apart from making the indentation consistent (I use uncrustify, but there are other tools that can do the job too), I added error checking to the scanf() statements, fixed the "%ch" format string (the h is superfluous, though mostly harmless), removed trailing spaces from printing, used a newline at the end of non-prompting printf() statements.

Your printing code wasn't printing enough; because of the way you're running your stack pointer, you need to print for (i = 0; i <= s.top; i++) with <= instead of <. A more orthodox way of using top has it showing the next space to use (so the number starts at zero and goes up to MAXLEN). There'd be a number of consequential changes to make.

However, there are some major curiosities left. You keep on passing stacks by value and returning them by value, rather than passing them by pointer. You're therefore passing 104 bytes to and from functions, which is quite a lot. In this code, efficiency isn't a big issue, but the style is unorthodox, shall we say. Your initialization stanza in main() is problematic, too:

stack s;
s.top = -1;
init(s);

The first line is fine. The second line sets top, and is OK in terms of "it works", but violates encapsulation. The next line has multiple problems. It takes a copy of the already initialized stack, sets top to -1, and returns the modified value. Your calling code, however, ignores the returned value.

If you passed pointers to your functions, you'd use:

void init(stack *s)
{
    s->top = -1;
}

and then:

stack s;
init(&s);

If you pass values, you could use:

stack s;
s = init(s);

though that's a bit pointless and you could use:

stack init(void)
{
    stack s;
    s.top = -1;
    return s;
}

and then call:

stack s = init();

Of these, passing by pointer is the normal mechanism for largish structures (where, if asked to specify 'largish', I'd say "16 bytes or more"). You can make exceptions on an informed basis, but be careful of the hidden costs of passing large structures by value. Also, changes made to the structures passed by value are not reflected in the calling function. You circumvent that by returning the modified value, but be cautious.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278