2010-08-12 45 views
1

斐伊川指針實現,陣列的使用C

我一直在試圖寫一個程序......我們已經具有等級字段和名字field.The指向此結構的結構存儲在一個數組固定大小。我有如下,我有一定的問題,實現了它...... 我寫的代碼是:

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

typedef struct 
{ 
int rank; 
char *name; 
}node; 

int insert(node **a , char name[] , int *rank) 
{ 
if(*rank >= 5) 
    { 
    printf("\n Overflow "); 
    return 0; 
    } 
    (*rank)++; 
    node *new = (node *)malloc(sizeof(node)); 
    new->name = name; 
    new->rank = *rank; 
    a[*rank] = new; 

    return 0; 
} 

int delete(node **a , int *rank) 
{ 
    int i = *rank; 
    if(*rank<0) 
    { 
    printf("\n No elements"); 
    return 0; 
    } 
    printf("\n Deleting %d , %s ",((a[*rank]))->rank,((a[*rank]))->name); 
    printf("\n Reordering the elements "); 
    while(i<5) 
    { 
    a[i] = a[i+1]; 
    } 
    return 0; 
} 

int display(node **a , int rank) 
    { 
    while(rank>0 && (a[rank])>0) 
    { 
    printf(" rank = %d name = %s \n",((a[rank])->rank),((a[rank])->name)); 
    rank--; 
    }    
    return 0; 
    } 

int main() 
{ 
    node *a[5] = {NULL}; 
    char ch = 'y'; 
    int choice,rank = -1; 
    char name[10]; 
    while(ch!='n' || ch!= 'N') 
    { 
    printf("\n Enter 1 to insert , 2 to delete , 3 to display and 4 to exit \n"); 
    scanf("%d",&choice); 
    switch(choice) 
    { 
     case 1: 
     printf("\n Enter name to insert"); 
     gets(name); 
     insert(a,name,&rank); 
     break; 
     case 2: 
     printf("\n Enter rank to delete "); 
     scanf("%d",&rank); 
     delete(a,&rank); 
     break; 
     case 3: 
     display(a,rank); 
     break; 
     case 4: 
     exit(0); 
     default: 
     printf("\n Invalid choice...please enter again "); 
     break; 
    } 
    ch = getchar(); 
    } 
return 0; 
} 

第一件事是系統自動進行選擇,除了第一次...(我不能」在那裏發現錯誤...),我對這個指針的東西有點困惑...請看看它是否正常...任何更正都歡迎,請給我一些解釋,爲什麼它是錯誤的,我們如何shd做...

謝謝

回答

2

首先,所有的函數總是返回0 - 甚至錯誤條件。如果你將等級作爲一個整數通過,並且返回它的新值,生活將變得如此簡單。

rank = insert(a, name, rank); 
/* : */ 
/* : */ 
int insert(node **a , char name[] , int rank) 
{ 
if(rank >= 5) 
{ 
    printf("\n Overflow "); 
    return 0; 
} 
rank++; 
node *new = (node *)malloc(sizeof(node)); 
new->name = name; 
new->rank = rank; 
a[rank] = new; 
return rank; 
} 

它已經多年,因爲我最後一次使用scanf,但我記得,你必須考慮在流,這意味着每個字符,「不要忘了輸入」。

scanf("%d\n",&choice); 

還與gets(name);,如果你輸入更多的塔9個字,你很擰的,因爲它會覆蓋你的程序的堆棧。

更新: 此外,你有兩種方式退出這個程序,除了一個永遠不會工作。你可以選擇選項「4」,這將呼籲exit(0)。或者,在每個命令結束時,您在逐步結束之前等待角色。看樣子你希望能夠進入「N」療法和退出,只是將無法正常工作:

while(ch!='n' || ch!= 'N') 

爲評估爲false,通道必須是「N」 &「N」的同時。你真的想

while(ch!='n' && ch!= 'N') 

UPDATE2: 我只是在你的代碼發現的最大問題。您的代碼中的任何地方都只指向main()中定義的單個數組。每次輸入新名稱時,它都會覆蓋該數組,並且由於每個節點都指向該數組,因此名稱在任何地方都會更改。你需要複製一份。 在插入():

node *new = (node *)malloc(sizeof(node));  
new->name = strdup(name); // use malloc internally. 

然後在刪除(),你需要釋放內存(說到這,你需要釋放節點有太多......)

printf("\n Deleting %d , %s ",((a[*rank]))->rank,((a[*rank]))->name);  
free(a[*rank]->name); 
free(a[*rank]); 
printf("\n Reordering the elements "); 

記住,無論您何時致電malloc,您最終都必須致電free

+0

不,你不需要'scanf()'格式的'\ n',這可能會導致它等待* extra *換行符。永遠不要使用'gets':使用'fgets'或者寫你自己的'getline'。 – schot 2010-08-12 14:42:01

+0

這並不能解決我的問題....事實上,我被要求只給出一次選擇......在第一次迭代中...... IT繼續對其餘的iters執行case 1。 – Flash 2010-08-12 14:55:23

0

我對使用「rank」變量感到困惑。 Main將它用作數組中最後一個節點的索引,並且這些節點將它用作排名。添加節點會增加它,但刪除節點不會減少它。

至少,我建議將index變量與ranking變量分開,以使邏輯更容易遵循。

就我個人而言,我會編寫一個結構來封裝具有自己的索引跟蹤和添加/刪除功能的數組。這樣,Main可以自由閱讀用戶選項並操作新節點的等級,而不用擔心數據結構的細節。

+0

實際上,結構的排名是陣列中存儲指向結構的指針的位置 – Flash 2010-08-12 14:57:00

+0

當您刪除節點時,將所有節點移動一個塊以下。但是你不會降低你轉移的節點的等級(所以他們的等級會不同步),並且你不會降低主等級變量(所以後面的增加會跳過一個位置)。另外,當你移動剩餘的元素時,你不會清除最後一個元素。所以你會在陣列的末尾加倍。 – Marc 2010-08-12 15:01:48

+0

是啊...我有點錯過了編碼dat – Flash 2010-08-12 17:20:18

0
while(ch!='n' || ch!= 'N') 
    { 
    printf("\n Enter 1 to insert , 2 to delete , 3 to display and 4 to exit \n"); 
    scanf("%d",&choice); getchar(); 
    . 
    . 
    . 
    //ch = getchar(); 
    } 

使用getchar()以及scanf()會導致此問題。由於在將字符讀入'ch'之後'\ n'作爲scanf的輸入。解決你的問題的一種方法是在讀取gets()之前讀取帶有額外getchar()的'\ n'。 你也應該修改while循環刪除。