繁体   English   中英

链表头部被尾部覆盖

[英]Linked List Head getting overwritten by tail

我试图通过实现不同的数据结构来使用 C。 我遇到一个问题,当我尝试从每次 while 循环迭代的命令行输入初始化链表时,头部不断设置为尾部,这是输入到 stdin 的最后一个命令

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

struct node {
    char value[512];
    struct node *next;
};


int main(int argc, char *argv[])
{

    struct node *head = malloc(sizeof(struct node));
    struct node **curr = &head;
    int flag = 1;
    int c = 0;

    while(flag == 1)
    {
        char cmd[512];
        struct node *new_node = malloc(sizeof(struct node));
        fgets(cmd, 512, stdin);
        cmd[strcspn(cmd, "\n")] = 0;

        if (strcmp(cmd,"exit") ==0){
            printf("Exiting\n");
            break;            
        } else {
            strncpy(new_node->value, cmd, 512);
            new_node->value[512 - 1] = '\0';
            (*curr)->next = new_node;
            *curr = new_node;
        }
    }

    printf("head value: %s\n", head->value);
    printf("curr value: %s", (*curr)->value);


    return 0;
}

我不明白为什么 head->value 和 curr->value 最终是一样的。 任何输入以及任何约定修复都将受到赞赏。 我不确定我是否以预期的方式编写 C。

谢谢,

我尝试使用不同的指针组合,我还尝试复制命令行条目而不是硬设置它。

不清楚是要将新节点插入到列表的开头还是列表的末尾。

如果要将新节点插入列表的开头,则必须在每次插入列表后更新head并将新节点的next成员设置为旧head

如果您想将新节点插入到列表的末尾,则必须使curr始终指向列表最后一个节点的next成员,或者如果列表为空,则使其指向head

您似乎没有应用上述两个选项。 相反,您使curr始终指向head并使head始终指向最近创建的节点。 您还使前一个头节点的next指针指向新的头节点。 换句话说,您正在使next指针指向错误的方向。 next的指针应该始终指向远离头部的方向,而不是指向头部。

这是一个在链表开头插入节点的示例程序:

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

#define MAX_STRING_LENGTH 512

struct node {
    char value[MAX_STRING_LENGTH];
    struct node *next;
};

int main( void )
{
    struct node *head = NULL;

    for (;;) //infinite loop, equivalent to while(1)
    {
        char cmd[MAX_STRING_LENGTH];
        struct node *new_node;

        //read one line of input
        if ( fgets( cmd, sizeof cmd, stdin ) == NULL )
        {
            fprintf( stderr, "Input failure!\n" );
            exit( EXIT_FAILURE );
        }
        cmd[strcspn(cmd,"\n")] = '\0';

        //check whether user wants to quit
        if ( strcmp( cmd, "exit" ) == 0 )
        {
            printf("Exiting\n");
            break;            
        }

        //allocate new node
        new_node = malloc( sizeof(struct node) );
        if ( new_node == NULL )
        {
            fprintf( stderr, "Memory allocation failure!\n" );
            exit( EXIT_FAILURE );
        }

        //set value of new node
        strcpy( new_node->value, cmd );

        //make new node point to old head
        new_node->next = head;

        //set head to new node
        head = new_node;
    }

    //print content of linked list
    printf( "\nThe head points to the address %p.\n", head );
    for ( struct node *p = head; p != NULL; p = p->next )
    {
        printf(
            "Node at address %p\n"
            "  has the value \"%s\"\n"
            "  and points to the address %p.\n",
             (void*)p, p->value, (void*)p->next
        );
    }

    //free the nodes
    for ( struct node *p = head; p != NULL; )
    {
        struct node *temp = p->next;
        free( p );
        p = temp;
    }

    return 0;
}

该程序具有以下行为:

node1
node2
node3
exit
Exiting

The head points to the address 0x559eea92aad0.
Node at address 0x559eea92aad0
  has the value "node3"
  and points to the address 0x559eea92a8c0.
Node at address 0x559eea92a8c0
  has the value "node2"
  and points to the address 0x559eea92a6b0.
Node at address 0x559eea92a6b0
  has the value "node1"
  and points to the address (nil).

这是一个示例程序,它在链表的末尾插入节点:

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

#define MAX_STRING_LENGTH 512

struct node {
    char value[MAX_STRING_LENGTH];
    struct node *next;
};

int main( void )
{
    struct node *head = NULL;
    struct node **pp_next = &head;

    for (;;) //infinite loop, equivalent to while(1)
    {
        char cmd[MAX_STRING_LENGTH];
        struct node *new_node;

        //read one line of input
        if ( fgets( cmd, sizeof cmd, stdin ) == NULL )
        {
            fprintf( stderr, "Input failure!\n" );
            exit( EXIT_FAILURE );
        }
        cmd[strcspn(cmd,"\n")] = '\0';

        //check whether user wants to quit
        if ( strcmp( cmd, "exit" ) == 0 )
        {
            printf("Exiting\n");
            break;            
        }

        //allocate new node
        new_node = malloc( sizeof(struct node) );
        if ( new_node == NULL )
        {
            fprintf( stderr, "Memory allocation failure!\n" );
            exit( EXIT_FAILURE );
        }

        //set value of new node
        strcpy( new_node->value, cmd );

        //make new node point to NULL
        new_node->next = NULL;

        //link new node to existing list
        *pp_next = new_node;

        //update pp_next to point to the new NULL pointer
        pp_next = &new_node->next;
    }

    //print content of linked list
    printf( "\nThe head points to the address %p.\n", head );
    for ( struct node *p = head; p != NULL; p = p->next )
    {
        printf(
            "Node at address %p\n"
            "  has the value \"%s\"\n"
            "  and points to the address %p.\n",
             (void*)p, p->value, (void*)p->next
        );
    }

    //free the nodes
    for ( struct node *p = head; p != NULL; )
    {
        struct node *temp = p->next;
        free( p );
        p = temp;
    }

    return 0;
}

该程序具有以下行为:

node1
node2
node3
exit
Exiting

The head points to the address 0x5568056a06b0.
Node at address 0x5568056a06b0
  has the value "node1"
  and points to the address 0x5568056a08c0.
Node at address 0x5568056a08c0
  has the value "node2"
  and points to the address 0x5568056a0ad0.
Node at address 0x5568056a0ad0
  has the value "node3"
  and points to the address (nil).

暂无
暂无

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

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