C语言 链接列表头被尾覆盖

vlju58qv  于 2023-01-25  发布在  其他
关注(0)|答案(1)|浏览(155)

我试图通过实现不同的数据结构来使用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。
谢谢你,
我尝试使用不同的指针组合,并且我还尝试复制命令行条目而不是硬设置它。

ijxebb2r

ijxebb2r1#

不清楚是要将新节点插入到列表的开头还是列表的结尾。
如果要在列表的开头插入新节点,则必须在每次插入列表后更新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).

相关问题