2014-01-18 278 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