2017-06-06 132 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()將其轉換爲數字。