我的链接列表遇到了一个小问题。 我用字符串构建了一个链接列表,它运行得很好。 现在,由于我使用 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;
}
}
最佳答案
在 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++ 开始,您可以用各种更现代的语言编写非常更紧凑、可靠和高效的等效程序。
现在,如果你只是一名学生,被一位老教授要求做一些尘土飞扬的 C 作业,并希望由一位 StackOverflow 贡献者的老教授为你完成,那么......这是你的幸运日.
关于c - 在链表上存储字符串的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20896038/