繁体   English   中英

C中字符串链表的问题

[英]Problems with Linked List of String in C

我正在尝试制作一个 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;
}

但这是我的输出:

#hello

hello

#adding

adding

#to list

to list

#history

history

history

history

history

因此,它不是打印出所有命令,而是打印出history而我不知道我做错了什么。 请帮助,我已经有一段时间没有接触 C 和指针了。

您的create_node()实现错误。

您正在为node::data成员泄漏malloc()内存,因为您立即重新分配node::data以指向输入char*参数所指向的同一内存,从而丢失了malloc ' ed 记忆。

因此,您创建的所有节点最终都指向main()中的同一个char[]缓冲区,该缓冲区被用户输入的每个字符串重复使用。

create_node()需要复制char数据,这可能是您打算做的,但没有正确执行。 尝试这个:

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

然后你需要添加一个新函数来在你使用完每个节点后释放它的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