2014-01-18 109 views
0

我的項目存在問題。我寫了一個函數,它從文件中讀取一個結構,按字母順序排序並寫回文件。從文件中讀取並放回去是可以的,因爲我在其他函數中使用相同的代碼,並且它非常完美。 我的排序有問題,因爲使用此功能後txt文件爲空。 它的工作在結構上的功能外:C:按字母順序排列列表

typedef struct baseofwords         
    { 
     char *word; 
     char *category; 
     struct baseofwords* next; 
    } base; 

這裏是我的功能:

void SORTING (base **head) 
{ 
char word[30]; 
char category[20]; 
FILE *fp; 
if ((fp = fopen("baza.txt", "r"))==NULL) 
    {printf("Error while opening the file!"); 
    exit(EXIT_FAILURE);} 
else 
    { 
    while(!feof(fp)) 
     { 
     fscanf(fp,"%s %s \n", word, category); 
     base *wsk = *head; 
     base *new = malloc (sizeof(base)); 
     new -> next = NULL; 
     new -> word = strdup(word); 
     new -> category = strdup(category); 
     if(wsk == NULL) 
      { 
      new -> next = *head; 
      *head = new; 
      } 
     else 
      { 
      while(wsk -> next != NULL) 
      wsk = wsk -> next; 
      wsk -> next = new; 
      } 
     } 
    } 
fclose(fp); 
//==========================================up until here it works, problem must be down there 


base *newHead = NULL; 
base *wsk1, *wsk2, *tmp; 
wsk1 = tmp = *head; 
wsk2 = NULL; 
while(tmp->next) 
    { if (tmp->next->word > wsk1->word) 
     { wsk2 = tmp; 
     wsk1 = tmp->next; 
     } 
    tmp = tmp->next; 
    } 
if (wsk2) wsk2->next = wsk1->next; 
else *head = wsk1->next; 
wsk1->next = newHead; 
newHead = wsk1; 
*head = newHead; 


//======================this part is okay again 
if ((fp = fopen("base.txt", "w"))==NULL) 
    {printf("Error while opening file!"); 
    exit(EXIT_FAILURE);} 
else 
    {base *wsk = *head; 
    while (wsk->next != NULL) 
    {fprintf(fp, "%s %s\n", wsk->word, wsk->category); 
    wsk=wsk->next;} 
    }fclose(fp); 
} 

非常感謝您提前幫助!

+0

這條線如何:base * new = malloc(sizeof(baza)); ?我甚至不知道它是如何編譯的... – GreenAsJade

+0

對不起!我從我的語言翻譯它。它是base * new = malloc(sizeof(base)); , 當然! – user3188206

+1

我認爲如果我們查看您使用的實際代碼會更好,或者甚至更好......如果您在發佈它之前編輯並測試您在此處發佈的代碼,並說它「有效」... – GreenAsJade

回答

1

有幾件事情是錯在這裏,讓我們來看看這個循環:

while(tmp->next) 
    { if (tmp->next->word > wsk1->word) 
     { wsk2 = tmp; 
     wsk1 = tmp->next; 
     } 
    tmp = tmp->next; 
    } 

您分配東西wsk2,然後從來沒有使用它。您嘗試通過比較word的地址(而不是該地址的值)來比較word。我不明白你是如何重新訂購物品的。

比較兩個字符串,你需要使用strcmp,你還需要決定你想要他們什麼順序。

其次,你不能僅僅通過一次步進排序列表。你將不得不具有嵌套循環來比較項目,並執行可能的多次移動來移動項目到位。

並且對鏈接列表中的項目進行重新排序(單個鏈接不低於),是相當困難的並且充滿了必須考慮的邊緣條件。當您想交換兩個項目時,您應考慮將指針移至wordcategory。這可能看起來像這樣:

void swapbases(base *it1, base *it2) 
{ 
    base tmp= * it1 ; 
    it1-> word= it2-> word, it1-> category= it2-> category ; 
    it2-> word= tmp.word, it2-> category= tmp.category ; 
} 

然後寫幾個循環,逐步通過,並找到項目的順序。有一個可怕的叫做冒泡排序:

int swaps ; 
for (swaps= 1 ; (swaps) ;) 
{ 
    swaps= 0 ; 
    for (tmp= head ; (tmp-> next) ; tmp= tmp-> next) 
    { 
    if (strcmp(tmp-> word, tmp-> next-> word) < 0) 
     { swapbases(tmp, tmp-> next) ; swaps ++ ; } 
    } 
} 
+0

是的,它看起來像while {{}之後的代碼應該以某種方式在它內部(因爲它是在使用wsk2的代碼之後) – GreenAsJade

+0

非常感謝您向我解釋所有內容耐心地!現在我看到了我的錯誤。我在{while}之後刪除了部分,並添加了您告訴我的內容。現在它正確地保存了列表,但仍未排序。 – user3188206