我的链接列表中有一个小问题。 我用字符串构建了一个链表,它运行得很好。 现在因为我正在使用strtok()来分隔字符串,我需要帮助分别存储结构但保持连接。 希望我解释得很好
现在这就是我所拥有的:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dict_word *word;
typedef struct node *Node;
typedef struct double_linked_list *DLL;
struct dict_word
{
char words[100];
int year[10];
char eng_synonyms[100];
char heb_synonyms[100];
};
struct node
{
word data;
Node *next;
Node *previous;
};
struct double_linked_list
{
Node *head;
Node *last;
};
char *split(char words[100])
{
int i;
char *word=strtok(words, "_#_");
char *year=strtok(NULL, "_#_");; // assigning NULL for previousely where it left off
char *definition=strtok(NULL,"_#_");
char *synonyms=strtok(NULL,"_#_");
i=atoi(year);
printf("%s\n", word);
printf("%i\n",i);
printf("%s\n", definition);
printf("%s\n", synonyms);
return 0;
}
这是我通过只有一个字符串来插入节点的功能:
void insert_beginning(char words[99])
{
struct node *var, *temp;
var=(struct node *)malloc(sizeof(struct node)); //explination about the (node *)
strncpy(var->data, words,99);
if (head==NULL)
{
head=var;
head->previous=NULL;
head->next=NULL;
last=head;
}
else
{
temp=var;
temp->previous=NULL;
temp->next=head;
head->previous=temp;
head=temp;
}
}
答案 0 :(得分:1)
我有点惊讶于在2014年看到用于处理此类抽象数据的普通C代码。
尽管如此,我认为您应该将实际的图书数据与列表分开。
strtok
将修改您的初始字符串(在每个标记的末尾插入'\ 0')。如果要访问各个位strtok
已将字符串拆分为,则必须记住所有指向标记的指针(字,定义等)。
所以你应该创建一个结构来把所有这些结合起来:
typedef struct {
const char * words;
int year;
const char * definition;
const char * synonyms;
} dict_word;
现在要创建一个新记录,您必须复制各种令牌,就像之前在链接列表中插入一样。
但这次使用strdup
功能可以更快地复制副本。
dict_word * create_record (char * raw) // raw record string
{
// allocate a new object
dict_word record = (dict_word *) malloc (sizeof (record));
assert (record != NULL);
/*
* sanity checks left out for concision,
* but you should make sure your input is properly formatted
*/
// populate the fields
record->word = strdup (strtok(raw , "_#_"));
record->year = atoi (strtok(NULL, "_#_"));
record->definition = strdup (strtok(NULL, "_#_"));
record->synomyms = strdup (strtok(NULL, "_#_"));
// done
return record;
}
您需要一个清理功能来释放记录创建过程中分配的所有内存:
void delete_record (record * r)
{
// first free all strings
free (r->word);
free (r->definition);
free (r->synomyms);
// then free the object
free (r);
}
现在列出清单。
您可以将列表定义为更独立的对象,而不是将处理列表的代码与关注书籍的代码混合在一起:
typedef struct sNode {
struct sNode * next;
struct sNode * prev;
void * data; // this will point to the linked objects
} listNode;
typedef struct
{
listNode *head;
listNode *tail; // either first/last or head/tail, but keep it consistent :)
} List;
首先,您需要初始化列表:
void List_init (List * l)
{
l->head = l->tail = NULL;
}
然后你想要添加元素
void List_put (List * list, void * data)
{
// allocate a node
listNode * node = (listNode *) malloc (sizeof (node));
assert (node != NULL);
// store data reference
node->data = data;
// insert the node at the end of list
node->prev = list->tail;
node->next = NULL;
list->tail = node;
if (list->head == NULL) list->head = node;
}
最后,要使用所有这些:
// create the list
List book_list;
List_init (&book_list);
/* ... */
// create the records
char * raw_record;
while ((raw_record = read_from_database ()) != DONE_READING)
{
List_put (book_list, create_record (raw_record));
}
/* ... */
// browse the records
listNode * node;
for (node = book_list->head; node != NULL; node = node->next)
{
dict_word * record = (dict_node *) node->data;
// do whatever you want with your record
}
所有这些都说完了,C不足以处理这种高级数据。
从C ++开始,你可以用各种更现代的语言写一个 非常 更紧凑,可靠和高效的等价物。
现在,如果你只是一名学生,请一位教授的旧geezer做一些尘土飞扬的C作业,并希望由StackOverflow撰稿人的旧geezer为你完成,那么......这是你的幸运日