简体   繁体   English

C中字符串链表的问题

[英]Problems with Linked List of String in C

I'm trying to make a minishell and store all the commands the user types, and when the user enters history it should display all the commands the user has typed so far, and when the user types history -c then it should clear the linked list.我正在尝试制作一个 minishell 并存储用户输入的所有命令,当用户输入history它应该显示用户迄今为止输入的所有命令,当用户输入history -c时,它应该清除链接列表。

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>

typedef struct node
{
    char* data;
    struct node *next;
} node;

node *create_node(char* data)
{
    node *ptr = malloc(sizeof(node));
    if (ptr == NULL)
    {
        fprintf(stderr, "Error: Out of memory in create_node()\n");
        exit(1);
    }
    
    ptr->data = data;
    ptr->next = NULL;
    return ptr;
}

node *insert_node(node *head, char* data)
{
    node *temp;
    if (head == NULL)
        return create_node(data);
    temp = head;
    while (temp->next != NULL)
    {     
        temp = temp->next;
    }
    // 'temp' is pointing to the last node in the list now.
    temp->next = create_node(data);
    return head;
}

void print_list(node *head)
{
    node *temp;
    if (head == NULL)
    {
        printf("(empty list)\n");
        return;
    }

    for (temp = head; temp != NULL; temp = temp->next)
        printf("%s%c", (char*)temp->data, '\n');
}

int main (int argc, char ** argv)
{
    char buf[1024];
    char * args[MAX_ARGS];
    char ** arg;
    node *head = NULL;
    while (1)
    {
        printf("#");
        if (fgets (buf, 1024, stdin ))
        {
            head = insert_node(head, buf);
            arg = args;
            *arg++ = strtok(buf, SEPARATORS);  // tokenize input
            while ((*arg++ = strtok(NULL, SEPARATORS)));
            if (args[0])
            {
                //#byebye command, exist the while loop.
                if (!strcmp(args[0], "byebye")) {
                    break;
                }      
  
                if (!strcmp(args[0], "history"))
                {
                    // command history with flag c

                    if (args[1] && !strcmp(args[1], "-c"))
                    {
                        // clear the linked list
                    } 
                    else
                    {
                        print_list(head);
                        printf("\n");
                    }
                    continue;
                }
                arg = args;
                while (*arg) fprintf(stdout, "%s ", *arg++);
                fputs ("\n", stdout);
            }
        }
    }
    return 0;
}

But this is my output:但这是我的输出:

#hello

hello

#adding

adding

#to list

to list

#history

history

history

history

history

So, instead of printing out all the commands, it prints out history and I don't know what I am doing wrong.因此,它不是打印出所有命令,而是打印出history而我不知道我做错了什么。 Please help, it has been awhile since I touched C and pointers.请帮助,我已经有一段时间没有接触 C 和指针了。

Your create_node() is implemented wrong.您的create_node()实现错误。

You are leaking the memory you malloc() for the node::data member, as you are immediately re-assigning the node::data to point at the same memory that the input char* parameter is pointing at, thus losing the malloc 'ed memory.您正在为node::data成员泄漏malloc()内存,因为您立即重新分配node::data以指向输入char*参数所指向的同一内存,从而丢失了malloc ' ed 记忆。

As such, all of your created nodes end up pointing at the same char[] buffer in main() , which is being reused for every string the user types in.因此,您创建的所有节点最终都指向main()中的同一个char[]缓冲区,该缓冲区被用户输入的每个字符串重复使用。

create_node() needs to make a copy of the char data, which is probably what you intended to do, but didn't do so correctly. create_node()需要复制char数据,这可能是您打算做的,但没有正确执行。 Try this:尝试这个:

node *create_node(char* data)
{
    node *ptr = malloc(sizeof(node));
    if (ptr == NULL)
    {
        fprintf(stderr, "Error: Out of memory in create_node()\n");
        exit(1);
    }

    ptr->data = strdup(data);
    ptr->next = NULL;

    if (ptr->data == NULL)
    {
        fprintf(stderr, "Error: Out of memory in create_node()\n");
        free(ptr);
        exit(1);
    }

    return ptr;
}

And then you need to add a new function to free each node and its data when you are done using it, eg:然后你需要添加一个新函数来在你使用完每个节点后释放它的data ,例如:

node* free_node(node* n)
{
    node *next = n->next;
    free(n->data);
    free(n);
    return next;
}

...

int main (int argc, char ** argv)
{
    node *head = NULL;
    ...

    while (head != NULL) {
        head = free_node(head);
    }

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM