2017-06-06 115 views
-1

当我将x插入程序时,如何显示堆栈。如何显示堆栈C

#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) 

    { 

当我插入的“x”我想程序显示栈和退出,但之后我在这个节目中插入X将是无限循环并且不显示堆栈,不要退出它不起作用我该怎么办????。

 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

与您的问题无关,但在C规范中明确提到只使用输入流(如stdin)调用'fflush'为* undefined behavior *。一些图书馆将它作为扩展来实现,但你应该避免这样做。 –

+2

与您的问题更相关的可能是您在初始化之前使用'value',因此具有* indeterminate *值。也请花一些时间阅读[如何调试小程序](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。 –

回答

0

我发现你的问题!这是一个令人头疼的问题,因为该程序总是要无限循环! 但问题是您正在阅读scanf("%d",&value)的字符。这个scanf不会从缓冲区中删除输入,所以你之后所做的每个scanf都会有相同的输入('x'),这是scanf无法读取的。

为了解决这个问题改变这些行:

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

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

所以,如果scanf函数不成功,那么你假设用户想要退出。

这也是一个重复的问题,租赁请参阅this question,了解更多详情。

1

一些程序员已经花花公子发现,但我想多一点明确:

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

X和值是未初始化的,他们可以持有任何价值。如果你比较它们,它们不太可能匹配,但即使在你第一次进入循环(导致立即退出)时它们也可能会意外。这是非常不可能的,那就是,可变x持有'x' –到底值时,它是不确定的行为无论如何读未初始化的变量...

下一个问题是:您只需使用scanf("%d")。如果您输入'x'字符,则无法尝试读取输入,因为该字符不能被扫描为数字。所以你必须先读一个字符串然后解析它。这两个错误固定在一起,你的代码可能是这样的:

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); 
    } 
} 

正在扫描后附加字符数(重要:空格字符之前需要跳过空格,即终止换行符从与fgets了)同时检查sscanf的返回值是否检测到无效输入,例如'abc'或'1xyz'。

另外,看看你的popStack功能:

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

这将始终是真实的,甚至它的顶部是NULL:那么var为空,也和NULL是等于本身的课程...

你还是做这种方式:

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

好的做法是始终检查的malloc的返回值。虽然它不应该在像你这样的小程序中失败,但如果你习惯于从头开始写更大的程序,你不会忘记它......

加上一些代码简化(被承认,唯一的化妆品,但如果是没有必要的...):

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

最后一个建议:你的两个函数形成功能对,所以喜欢在他们的名字反映了这一点,太:无论是“推”和“流行“或”pushStack“和”popStack“。

0

您对valuex的比较始终会调用未定义的行为。 value的范围是循环体。实际上,每当你循环时你都会得到一个“新”value

您的scanf正在寻找一个号码。如果您希望在您按下键盘上的x键时终止循环,它将不起作用。 scanf实际上将失败,因为x不是%d的有效匹配序列。另一方面,如果您输入的120x的ASCII码,您可能会感到非常幸运并且看到循环终止,因为未定义的行为可能包括在循环的每次迭代中重复使用value的相同位置。

要解决此问题,请在比较之前定义读取值,以确定它是否为x。此外,你必须使用例如fgets()来阅读它,然后检查它是否它x,然后,如果它不是可能使用strtol()sscanf()将其转换为数字。