在链接列表中存储字符串的元素

时间:2014-01-03 03:29:01

标签: c string linked-list

我的链接列表中有一个小问题。 我用字符串构建了一个链表,它运行得很好。 现在因为我正在使用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;
}
 }

1 个答案:

答案 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为你完成,那么......这是你的幸运日