C中的链接列表

Sri*_*aju 3 c linked-list

我在运行此链表实现(包含单词作为数据)时遇到了一些问题.问题是当我尝试在链接列表中打印单词(我插入的)时,我什么都没得到.我做错了什么,打破了我的头脑?我希望这不是什么傻事.无论如何这里是代码 -

typedef struct node
{
    void *data;
    struct node *next;
} NODE;

NODE *new_node(void *data)
{
    NODE *new = malloc(sizeof(NODE));
    if(new)
    {
        new->data = data;
        new->next = NULL;
        return new;
    }
    else
    {
        return NULL;
    }
}

void print_list(NODE *head, void (print_fn) (void*))
{
    if(head && head->next)
    {
        while(head->next)
        {
            if(print_fn)
                print_fn(head->data);
            else
                printf("Word: %s\n", (char *)head->data);
            head = head->next;
        }
    }
    return;
}

void append(NODE **head, NODE *node)                                                                                  
{
    NODE *tmp = *head;
    if(tmp && node)
    {
        while(tmp->next)
            tmp = tmp->next; 
        (*head)->next = node; /*add as last node*/
    }
    return;
}


NODE *create_list()
{
    FILE *dict_file = fopen("trial.txt", "r");

    if(dict_file)
    {
        NODE *head = new_node(NULL);
        if(!head) return NULL;

        char word[20];
        int first  = TRUE;
        memset(word, '\0', 20);

        while(fgets(word, sizeof(word), dict_file) != NULL )
        {
            if(first)
            {
                head->data = (void*)word;
                first = FALSE;
            }
            else
            {
                append(&head, new_node((void*)word));
            }
        }
        fclose(dict_file);
        return head;
    }
    else
    {
        printf("ERROR: File not found");
        return NULL;
    }
}

int main(int argc, char *argv[])
{
    NODE *head = create_list();

    if(!head)
    {
        printf("ERROR: Either malloc() failed or data not found\n");
        return FALSE;
    }
    else
    {
        print_list(head, NULL);
        return TRUE;
    }
}
Run Code Online (Sandbox Code Playgroud)

Ven*_*emo 15

这已经成为一个很长的答案.不要个人接受,但你犯了很多新手的错误.我在大学里遇到过很多人,我帮助他们学习了C语言和编程,所以我已经习惯了这些事情.

我能找到的重要问题

  • 您将指向堆栈变量的指针分配给words
    这是完全错误的,因为一旦执行离开创建它的函数,该值将被覆盖.解决方案:将该变量的内容复制到堆变量中.

  • 您的append功能有问题
    它将附加元素添加到第二个位置而不是最后一个位置.请注意,您最后也不需要返回.要求双指针作为append方法的输入也没有意义.此外,后分配headtmp,这是徒劳检查TMP反对NULL为好,因为它不会是NULL,如果head不是NULL.另外,我建议也要检查新节点NULL.如果是NULL,这将使您免于迭代整个集合.

  • create_list函数是次优
    Fist,第一个和其他情况之间的区别是徒劳的.引入另一个指针(current在我的代码中调用)将无需检查它是否是第一个.接下来,你总是调用append函数head,因此你总是需要迭代整个集合.这也可以通过引入current变量来优化.(在开始时,应该分配值head.)

  • print_list函数是错误的
    如果只有一个节点,则不会打印任何内容.它还冗余地检查指针是否为空.(循环的开头也会检查它.)此void函数末尾的return语句也是不必要的.

  • 当你不使用它时你应该释放内存
    @Baltasarq clear在他的回答中写了一个很好的函数,你应该使用它.:)

不严重的错误,但你应该知道它们

  • 您不应该使用void*而不是char* 如果您知道结构的data成员NODE将存储字符,为什么使用void*?这是不好的做法!(当然,除非你有充分的理由.)

  • 使用new单词作为变量名使您的代码不符合C++.因此,我建议不要这样做.

  • 请采用更好的编码风格 - 这将使您的代码更容易阅读

  • 不一致:如果print_list你没有分配一个新的变量来通过集合(就像你对tmp变量所做的那样append)那么将参数命名为是错误的head.(我node在我的代码中将其重命名为.)

这是固定代码

(请注意,可能存在小的语法错误,因为我在没有实际测试的情况下将代码键入浏览器.)

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

typedef struct node
{
    void *data;
    struct node *next;
} NODE;

NODE *new_node(void *data)
{
    NODE *newNode = (NODE*)malloc(sizeof(NODE));
    if (newNode)
    {
        newNode->data = data;
        newNode->next = NULL;
        return newNode;
    }
    return NULL;
}

void append(NODE *head, NODE *node)
{
    if (head && node)
    {
        NODE *tmp = head;
        while (tmp->next)
            tmp = tmp->next; 
        tmp->next = node; /* add as last node */
    }
}

void print_list(NODE *node, void (print_fn) (void*))
{
    while (node)
    {
        if (print_fn)
            print_fn(node->data);
        else
            printf("Word: %s\n", (char *)node->data);

        node = node->next;
    }
}

NODE *create_list()
{
    FILE *dict_file = fopen("trial.txt", "r");

    if (dict_file)
    {
        NODE *head = NULL;
        NODE *current = head;

        char word[20];
        memset(word, '\0', 20);

        while (fgets(word, sizeof(word), dict_file))
        {
            // Creating a variable on the heap
            char *data = calloc(sizeof(word) + 1, sizeof(char));
            // Copying the contents of words to it
            strcpy(data, word);

            append(current, new_node((void*)data));
            if (current->next)
                current = current->next
        }
        fclose(dict_file);
        return head;
    }
    else
    {
        printf("ERROR: File not found");
    }
    return NULL;
}

int main(int argc, char *argv[])
{
    NODE *head = create_list();

    if (!head)
    {
        printf("ERROR: Either malloc() failed or data not found\n");
    }
    else
    {
        print_list(head, NULL);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)