-1

How could I display stack when I insert x in to programs.

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

struct Node
{
    int Data;
    struct Node* next;
} * top;

void popStack()
{
    struct Node *temp, *var = top;
    if (var == top)
    {
        top = top->next;
        free(var);
    }
    else
        printf("\nStack Empty");
}

void push(int value)
{
    struct Node* temp;
    temp = (struct Node*)malloc(sizeof(struct Node));
    temp->Data = value;
    if (top == NULL)
    {
        top = temp;
        top->next = NULL;
    }
    else
    {
        temp->next = top;
        top = temp;
    }
}

void display()
{
    struct Node* var = top;
    if (var != NULL)
    {
        printf("\nElements are as:\n");
        while (var != NULL)
        {
            printf("\t%d\n", var->Data);
            var = var->next;
        }
        printf("\n");
    }
    else
        printf("\nStack is Empty");
}

int main(int argc, char* argv[])
{
    printf(" Wellcome to Basic Stacking. \n");
    top = NULL;
    while (1)

    {

when i insert "x" I want program to display stack and exit but it does not work after I insert x in this programs it will be infinite loop and don't display the stack and don't exit what should i do????.

        char x ;

        int value;  
        if (value != x)
        {

            printf("please enter Your Name:");
            scanf("%d", &value);
            push(value);
            fflush(stdin);
            display();
        }
        else
        {
            // popStack();
            display();
            break;
        }
    }
    getch();
}
  • 5
    Unrelated to your problem, but calling `fflush` with an input-only stream (like `stdin`) is explicitly mentioned in the C specification as *undefined behavior*. Some libraries implement it as an extension, but you should really refrain from doing it. – Some programmer dude Jun 06 '17 at 10:27
  • 2
    More related to your problem might be the fact that you use `value` before it is initialized, and therefore have an *indeterminate* value. Also please take some time to read about [how to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). – Some programmer dude Jun 06 '17 at 10:29

3 Answers3

1

Some programmer dude already spotted, but I want to be a little more explicit:

char x;
int value;  
if (value != x)

Both x and value are uninitialized, they could hold any value. If you compare them, it is very unlikely that they will match, but they could by accident even at the first time you enter the loop (leading to immediate exit). It is very unlikely, too, that variable x holds the value of 'x' – in the end, it is undefined behaviour anyway to read uninitialized variables...

Next problem is: You simply use scanf("%d"). This will fail trying to read input, if you type in an 'x' character, because that one cannot be scanned as a number. So you would have to read a string first and then parse it. Both errors fixed together, your code might look like this:

char buffer[128];
while(1)
{
    if(!fgets(buffer, sizeof(buffer), stdin))
        break; // some error occured
    if(*buffer == 'x') // you can compare directly, you don't need a char x = 'x'; ...
        break;
    int value;
    char c;
    if(sscanf(buffer, "%d %c", &value, &c) == 1)
    {
        // ...
    }
    else
    {
        puts("invalid input");
        fflush(stdout);
    }
}

Scanning for an additional character after the number (important: the space character before is needed to skip white space, i. e. the terminating newline character got from fgets) together with checking the return value of sscanf detects invalid input such as 'abc' or '1xyz'.

Additionally, have a look at your popStack function:

struct Node* var = top;
if (var == top)

This will always be true, even it top is NULL: then var is NULL, too, and NULL is equal to itself, of course...

You should rather do it this way:

if (top)
{
    struct Node* var = top;
    top = top->next;
    free(var);
}

Good practice is always checking the return value of malloc. Although it shouldn't ever fail in such a small program like yours, you won't forget it later when writing larger programs if you get used to right from the start...

Together with some code simplification (admitted, cosmetics only, but the if is not necessary...):

struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
if(temp)
{
    temp->Data = value;
    temp->next = top;
    top = temp;
}
else
{
    // appropriate error handling
}

One last recommendation: Your two functions form a functional pair, so prefer reflecting this in their names, too: either "push" and "pop" or "pushStack" and "popStack".

Aconcagua
  • 24,880
  • 4
  • 34
  • 59
0

I found out your problem! This was kinda of an headache since the program was always going for an infinite loop! But the problem is you are reading characters with scanf("%d",&value). This scanf doesn't remove the input from the buffer, so every other scanf you do after will have the same input ('x'), which your scanf can't read.

To fix this change these lines:

printf("please enter Your Name:"); scanf("%d", &value);

to

printf("please enter Your Name:"); if(scanf("%d", &value)==0)value=x;

So if scanf isn't successful then you assume the user wants to exit.

This is also a duplicate question, lease refer to this question, for more details.

H. Figueiredo
  • 888
  • 9
  • 18
0

Your comparison of value against x always invokes undefined behaviour. The scope of value is the loop body. Effectively you get a "new" value each time you go round the loop.

Your scanf is looking for a number. If you expect the loop to terminate when you press the x key on your keyboard, it is not going to work. The scanf will actually fail because x is not a valid match sequence for %d. On the other hand, if you type in 120 which is the ASCII code for x you might get lucky and see the loop terminate because the undefined behaviour might include reusing the same location for value on each iteration of the loop.

To fix this, define read value before you do the comparison to see if it is x. Also, you'll have to read it using, for example fgets(), then check it to see if it x and then, if it isn't maybe use strtol() or sscanf() to convert it to a number.

JeremyP
  • 84,577
  • 15
  • 123
  • 161