我的名单总是指向尾巴。有什么问题?
我的linked_list.h
:
#ifndef LINKED_LIST
#define LINKED_LIST
struct node
{
char *data;
struct node *nextElement;
struct node *prevElement;
};
void createList(struct node **head, struct node **tail);
void fill_list (char *word, struct node **head, struct node **tail);
#endif
main.c
:
#include <stdio.h>
#include <stdlib.h>
#include "linked_list.h"
#include <string.h>
int main()
{
FILE *dataFile;
char *word = (char *) calloc ( 255, sizeof(char) );
/* Create empty list */
struct node *head, *tail;
createList (&head, &tail);
/*------------------------*/
/* Data file open*/
dataFile = fopen("data.txt" ,"r");
if( dataFile == NULL )
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
/* Data reading */
while (( fscanf(dataFile, "%s", word) ) != EOF )
{
int i = 0;
int wordsCount = 0;
for (i = 0; i <= strlen(word); i++)
{
if ( (word[i] >= 'a') && (word[i] <= 'z') )
wordsCount = wordsCount + 1;
}
if ( wordsCount == strlen(word) )
{
fill_list ( word, &head, &tail );
}
}
fclose(dataFile);
return 0;
};
和linked_list.c
:
#include <stdio.h>
#include <stdlib.h>
#include "linked_list.h"
void createList(struct node **head, struct node **tail)
{
*head = NULL;
*tail = NULL;
}
void fill_list ( char *word, struct node **head, struct node **tail )
{
struct node *elem, *temp;
if ( (*head) == NULL )
{
// printf("HEAD = NULL\n");
elem = (struct node *) malloc ( sizeof (struct node) );
elem -> data = word;
elem -> nextElement = NULL;
elem -> prevElement = NULL;
(*head) = elem;
*tail = elem;
// printf("%s\n", (*head) -> data );
}
else
{
// printf("HEAD != NULL\n");
elem = (struct node *) malloc ( sizeof (struct node) );
elem -> data = word;
elem -> nextElement = NULL;
elem -> prevElement = *tail;
*tail = elem;
// printf("%s\n", (*head) -> data );
}
}
我的数据文件:qw erty b cc。
首先,head == NULL
,所以head -> data = 'qw'
,它应该始终为头,但它会变为erty,然后在每个循环步骤后变为b和cc。
我做错了什么?
答案 0 :(得分:3)
问题是您对所有输入使用相同的字符串,并将其用于所有节点。这意味着所有节点的data
成员都指向同一个字符串。这个字符串当然只包含你上次读到的内容。
您可能希望将字符串缓冲区保留在main
中作为普通数组(而不是在堆上分配它)并使用例如strdup
复制节点的字符串。不要忘记稍后释放它们。
指针正是它听起来的样子,它是指向到内存中某个其他位置的变量。你可以有许多指针都指向同一个内存。
在您的情况下,您将函数word
中的指针main
传递给我们对fill_list
的所有调用。这意味着您在fill_list
中创建的所有节点将使用完全相同的指针,并且它们都将指向完全相同的内存。
这意味着列表中的所有节点都会使data
成员的值相同,并且它始终是word
函数中读入main
的最后一个字符串。
如果您使用strdup
之类的功能,它将复制字符串。即它将为字符串分配全新的内存,并从旧区域复制到新分配的区域,并返回指向新分配的内存的指针。
答案 1 :(得分:1)
试试这个
void fill_list ( char *word, struct node **head, struct node **tail )
{
struct node *elem, *temp;
/* you need to create node first ! */
elem = (struct node *) malloc ( sizeof (struct node));
elem -> data = NULL ;
elem -> data = (char*) malloc( sizeof(char)*255));
if ( elem -> data == NULL )
{
perror("alloc data failed ");
}
if ( (*head) == NULL )
{
// printf("HEAD = NULL\n");
/* call memcpy() function need to #include <string.h> */
elem -> data = memcpy((void*)elem -> data,(void*)word,strlen(word));
elem -> nextElement = NULL;
elem -> prevElement = NULL;
(*head) = elem;
*tail = elem;
// printf("%s\n", (*head) -> data );
}
else
{
// printf("HEAD != NULL\n");
elem -> data = memcpy((void*)elem -> data,(void*)word,strlen(word));
elem -> nextElement = NULL;
elem -> prevElement = *tail;
*tail = elem;
// printf("%s\n", (*head) -> data );
}