c - 在链表上存储字符串的元素

标签 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;
}
 }

最佳答案

在 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/

相关文章:

C(Linux)-valgrind : Conditional jump or move depends on uninitialised value(s) after realloc

c++ - 如何理解链表?

java - 从单链表中删除最后一个节点(java)

c - 无法使用指向该变量的指针更改其他函数中局部变量的状态

c++ - imread : QNativeImage: Unable to attach to shared memory segment 的 C 包装器中的 OpenCv 错误

c - 如何为结构中的 int 数组分配内存

c - 语言规范中定义的 C 语言(类型名称)的用法在哪里?

arrays - 在 Ruby 中,如何在给定要分解字符串的索引数组的情况下分解字符串?

python - 数据框:如何删除字符串中的点

c++ - 有没有一种简单的方法来迭代 C++ 中的静态字符串列表