Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何写入对单链表结构的更改?_C - Fatal编程技术网

C 如何写入对单链表结构的更改?

C 如何写入对单链表结构的更改?,c,C,我需要创建一个程序,其中将创建一个简单的学生单链表。我需要让它有可能改变一个给定学生的名字。 因此,不会记录对结构的更改。我没有得到关于成功录制的输出。 我的错误是什么?如何纠正? main.c代码: #include <stdio.h> #include <string.h> #include <windows.h> #define MAX 10 #define KOL 15 struct Student { int id; char Na

我需要创建一个程序,其中将创建一个简单的学生单链表。我需要让它有可能改变一个给定学生的名字。 因此,不会记录对结构的更改。我没有得到关于成功录制的输出。 我的错误是什么?如何纠正? main.c代码:

#include <stdio.h>
#include <string.h>
#include <windows.h>
#define MAX 10
#define KOL 15

struct Student
{
    int id;
    char Name[KOL];
    int Age;
    float AverageRaiting;
    struct Student* nextStudent;
};

void InitStudentList(struct Student** student)
{
    *student = (struct Student*)
        malloc(sizeof(struct Student));
    (*student)->id = 1;
    printf("Enter 1 student name: ");
    scanf("%s", (*student)->Name);
    printf("Enter 1 student age: ");
    scanf("%d", &(*student)->Age);
    printf("Enter 1 student average raiting: ");
    scanf("%f", &(*student)->AverageRaiting);
    printf("\n");
    (*student)->nextStudent = NULL;
    struct Student* endStudent = *student;
    for (int i = 2; i <= MAX; i++)
    {
        endStudent->nextStudent =
            (struct Student*) malloc(sizeof(struct Student));
        endStudent = endStudent->nextStudent;
        endStudent->id = i;
        printf("Enter %d student name: ", i);
        scanf("%s", endStudent->Name);
        printf("Enter %d student age: ", i);
        scanf("%d", &endStudent->Age);
        printf("Enter %d average raiting: ", i);
        scanf("%f", &endStudent->AverageRaiting);
        printf("\n");
        endStudent->nextStudent = NULL;
    }
}

void PrintList(struct Student* student)
{
    struct Student* printStudent = student;
    printf("==========================\n");
    printf("Номер         Ім’я         Вік  Рейтинг \n");
    printf("==========================\n");
    while (printStudent)
    {
        printf("%d", printStudent->id);
        printf("%-15s", printStudent->Name);
        printf("%4d", printStudent->Age);
        printf("%8.2f", printStudent->AverageRaiting);
        printf("\n");
        printStudent = printStudent->nextStudent;
    }
    printf("==========================\n");
}

void FreeList(struct Student** student)
{
    if (*student == NULL)
        return;
    struct Student* tmp = *student;
    struct Student* curr_stud;
    while (tmp)
    {
        curr_stud = tmp;
        tmp = tmp->nextStudent;
        free(curr_stud);
    }
    *student = NULL;
}

void ChangeStudentName(int n, char name[KOL], struct Student* students)
{
    struct Student* st = 0;
    for (st = students; st < students + MAX; st++)
    {
        if (st->id == n)
        {
            const int size=sizeof(st->Name);
            if(size && size>=sizeof(name))
            {
                memcpy(st->Name,name,size);
                st->Name[size-1]='\0';
            }
            printf("Changes are recorded");
            break;
        }
    }
}

int main(void)
{
    int command;
    struct Student* BaseStudent = NULL;
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    InitStudentList(&BaseStudent);
    for (;;)
    {
        printf("Enter command:\n 1 - Show students list,\n 2 - Change student name,\n 3 - Exit\n");
        scanf("%d", &command);
        switch (command)
        {
        case 1:
            PrintList(BaseStudent);
            break;
        case 2:
        {
            int n;
            char name[KOL];
            printf("Enter student number: ");
            scanf("%d", &n);
            printf("Enter new student name: ");
            scanf("%s", &name);
            ChangeStudentName(n, name, BaseStudent);
            break;
        }
        case 3:
            FreeList(&BaseStudent);
            return 0;
            break;
        default:
            printf("Error...");
            FreeList(&BaseStudent);
            return 0;
            break;
        }
    }
    return 0;
}

但它也不起作用…

您正在混合使用链表和数组

您定义的结构和初始化学生的函数表明您确实在使用列表。 列表中的条目通过指针连接。通过应用指针算法,您无法访问列表中的下一个条目,这与索引数组基本相同

让我们看看您的功能:

void ChangeStudentName(int n, char name[KOL], struct Student* students)
{
    struct Student* st = 0;
    for (st = students; st < students + MAX; st++)  
此处的大小必须与KOL相同,因为Name是结构内部具有固定大小的数组。不需要检查

sizeofName也是指针的大小。数组仅作为指向函数的指针传递。无法获取函数中数组的大小

你也根本不需要比较这个。对于目标而言,实际字符串不太长就足够了。您可以使用strncpy来验证这一点。别忘了在之后终止字符串

            {
                memcpy(st->Name,name,size);
                st->Name[size-1]='\0';
            }
            printf("Changes are recorded");
            break;
        }
    }
}
更新版本如下所示:

strcpy(st->Name, name);
void ChangeStudentName(int n, char name[KOL], struct Student* students)
{
    struct Student* st = 0;
    for (st = students; st != NULL; st=st->nextStudent)
    {
        if (st->id == n)
        {
            strncpy(st->Name, name, sizeof(st->Name));
            st->Name[sizeof(st->Name)-1]='\0';

            printf("Changes are recorded");
            break;
        }
    }
}

; 这不是链表的工作方式。你是说st=st->nextStudent吗?由于访问无效的内存地址,这会导致UB。我是盲人,调试器无法完全访问。我知道带有for的代码块不能正确执行。但我不知道如何解决这个问题。
void ChangeStudentName(int n, char name[KOL], struct Student* students)
{
    struct Student* st = 0;
    for (st = students; st != NULL; st=st->nextStudent)
    {
        if (st->id == n)
        {
            strncpy(st->Name, name, sizeof(st->Name));
            st->Name[sizeof(st->Name)-1]='\0';

            printf("Changes are recorded");
            break;
        }
    }
}