无法将新节点添加到链表

Can't add new node to linked list

我正在尝试编写一个函数,在 likded 列表的末尾添加新节点,但程序因未知原因终止。我添加了 "Works for now" 个图章来可视化正在发生的事情。 看起来程序在 if (*first == NULL) {...}

之前终止

代码:

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

struct student
{
    int ID;
    char name[50];
    char surname[50];
    struct student *next;
};

void insertattheend(struct student **first)
{
    struct student *new = (struct student *)malloc(sizeof(struct student));
    struct student *last = *first;
    int Idtemp;
    char Nametemp[50], Surnametemp[50];
    printf("ID: ");
    scanf("%d", &Idtemp);
    printf("Name: ");
    scanf("%s", Nametemp);
    printf("Surname: ");
    scanf("%s", Surnametemp);
    new->ID = Idtemp;
    int i;
    for (i = 0; i < 50; i++)
    {
        new->name[i] = Nametemp[i];
        new->surname[i] = Surnametemp[i];
    }
    printf("Works for now\n");
    new->next = NULL;
    printf("Works for now\n");
    if (*first == NULL)
    {
        printf("Works for now\n");
        *first = new;
        printf("Works for now\n");
        return;
    }

    while (last->next != NULL)
        last = last->next;

    last->next = new;
    return;
}

void printlist(struct student *oof)
{
    while (oof != NULL)
    {
        printf("ID: %d\nName: %s\nSurname: %s ", oof->ID, oof->name, oof->surname);
        oof = oof->next;
    }
}

int main(void)
{
    struct student *head = NULL;
    head = (struct student *)malloc(sizeof(struct student));
    char operation;
    // a - insert
    printf("Choose operation: ");
    scanf("%c", &operation);
    if (operation == 'a')
        insertattheend(&head); // add element

    printlist(head);
    return 0;
}

输出

Choose operation: a
ID: 12
Name: John
Surname: Nhoj
Works for now
Works for now

我已经尝试了我能想到的一切。 有人知道如何使这项工作吗?感谢帮助

首先,您的头部插入不必要地复杂。您可以通过读入临时 student 而不是一大堆其他无关的缓冲区来显着缩短它。下面是一个半完整的例子:

void insertattheend(struct student **first)
{
    // this is where we'll read our data first
    struct student s = {0};

    // TODO: ALL of these need proper error checking to ensure
    //  they succeeded
    printf("ID: ");
    scanf("%d", &s.ID);
    printf("Name: ");
    scanf("%49s", s.name);
    printf("Surname: ");
    scanf("%49s", s.surname);

    // march 'first' down the pointer chain until it addresses 
    // the last pointer in the list (which wil be the 'head' 
    // pointer itself if the list is empty, or the 'next'
    // member of the last node if the list is not empty.
    while (*first)
        first = &(*first)->next;

    // allocate a new node
    *first = malloc(sizeof **first);
    if (*first == NULL)
    {
        perror("Failed to allocate new list node");
        exit(EXIT_FAILURE);
    }

    // structure copy 's' into the location pointed to by
    //  the pointer pointed to by 'first'
    **first = s;

    // done
}

其次,您的 main 不必要地为 head 指向的节点分配 space,而实际上它应该简单地从 NULL 开始并允许插入函数来管理它从那里。半完整程序如下所示。我怀疑您会遇到其他问题,其中一些问题我已经在这里巧妙地解决了。

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

struct student
{
    int ID;
    char name[50];
    char surname[50];
    struct student *next;
};

void insertattheend(struct student **first)
{
    // this is where we'll read our data first
    struct student s = {0};

    // TODO: ALL of these need proper error checking to ensure
    //  they succeeded
    printf("ID: ");
    scanf("%d", &s.ID);
    printf("Name: ");
    scanf("%49s", s.name);
    printf("Surname: ");
    scanf("%49s", s.surname);

    // march 'first' down the pointer chain until it addresses 
    // the last pointer in the list (which wil be the 'head' 
    // pointer itself if the list is empty, or the 'next'
    // member of the last node if the list is not empty.
    while (*first)
        first = &(*first)->next;

    // allocate a new node
    *first = malloc(sizeof **first);
    if (*first == NULL)
    {
        perror("Failed to allocate new list node");
        exit(EXIT_FAILURE);
    }

    // structure copy 's' into the location pointed to by
    //  the pointer pointed to by 'first'
    **first = s;

    // done
}

void printlist(const struct student *oof)
{
    while (oof != NULL)
    {
        printf("ID: %d\nName: %s\nSurname: %s\n", oof->ID, oof->name, oof->surname);
        oof = oof->next;
    }
}

void deletelist(struct student *lst)
{
    while (lst)
    {
        struct student *tmp = lst;
        lst = lst->next;
        free(tmp);
    }
}

int main(void)
{
    struct student *head = NULL;
    char operation;

    printf("Choose operation: ");
    scanf(" %c", &operation);
    if (operation == 'a')
        insertattheend(&head); // add element

    printlist(head);
    deletelist(head);
    return 0;
}