2011-02-01 63 views
0

我正在尝试读取文本文件并将每行存储在类型为void *的链接列表的节点中。 这是列表的头文件。链接列表类型void *

#ifndef LINKEDL 
#define LINKEDL 

struct node_s { 
    void *data; 
    struct node_s *next;  
}; 

struct node_s *node_create(void*); 
struct node_s *list_insert_after(struct node_s*, void*); 
struct node_s *list_insert_beginning(struct node_s*, void*); 
int list_remove(struct node_s*, struct node_s*); 
int list_foreach(struct node_s*, int(*)(void*)); 
int printstring(void *s); 


#endif 

所有的链接列表功能已经彻底的测试,所以我想这个问题是我如何使用它。我想要实现的是每个节点都有一条线,而我现在拥有的是每个节点的最后一条线。我猜这跟char指针有点关系,但已经花了两个小时没有突破,所以也许有人可以帮忙? 此外,我使用的列表是一个修改列表,如看到here

if (file == NULL) 
{ 
    perror("Error opening file"); 
} 
else 
{ 
    char mystring[SIZE]; 
    char temp[SIZE]; 

    list = node_create((void*)mystring); 
    current = list; 
    while (fgets(mystring, SIZE, file) != NULL) 
     { 
      strcpy(temp, mystring); 
      printf("%d\t%s",counter++,temp); 
      current=list_insert_after(current, (void*)temp);      
      } 
      fclose(file); 

     } 

更新: 谢谢大家。

+1

你只需要一个字符串变量(MyString的),所以所有的节点将指着这个相同的字符串。您需要为每个新节点指向一个新字符串。 – 2011-02-01 17:15:42

回答

1

删除行:

strcpy(temp, mystring); 

并更改行:

current=list_insert_after(current, (void*)temp); 

current=list_insert_after(current, strdup(mystring)); 
+0

看到“免费”使用的例子也不错。 – 2011-02-01 17:25:04

3

您正在使用单个阵列temp创建每个节点。每当你读一行时,你用你读的最后一行替换temp的内容。这就是为什么每个节点都有最后一行(您指的是每个节点中的相同内存位置)。

你应该怎么做,是使用malloc为每行动态分配内存。因此,你应该把指向新分配的内存的指针传递给list_insert_after,而不是传递temp。

1

想一想 - 在栈上有一个临时字符数组,它会在退出(else块)范围时被破坏,并且将指向该数组的指针插入到列表中。因此毕竟,这个列表最终会有指向被破坏/不正确的数据的指针。行为是未定义的。

你必须为每个字符串动态地分配内存(并且不要忘记清理它)。 strdup可以在这里很有用。从列表中删除/删除字符串时,请不要忘记拨打free