链接列表的数据被覆盖

时间:2016-03-12 05:13:37

标签: c

我在将数据添加到链接列表时遇到问题。这个代码基本上是尝试首先在结构中插入新的课程名称,然后将结构插入到链表中,并重复循环。用户有责任插入新的课程名称。

现在的问题是当用户使用scanf转到添加课程操作时,它总是覆盖链接列表中的现有课程名称并添加到其中。

这是控制台应用程序的输入和输出:

Enter operation: 1
Add Course: asdgvsdrgf
Enter operation: 1
Add Course: ehtyerdc
Enter operation: 1
Add Course: nbcnvbergt
Enter operation: 5    (// Just Print course name in the linked list)
Current enrolments:
nbcnvbergt
nbcnvbergt
nbcnvbergt

Current enrolments:

(改变h文件是不可能的,因为这是大学转让的要求)

以下是附加的c和h文件:

bst.h

#pragma once

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

typedef struct bstNode {
long student_id;
struct bstNode *left;
struct bstNode *right;
} *BST;

courselist.h

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

typedef struct course {
char *name;
BST students;
} Course;

typedef struct courseNode {
Course data;
struct courseNode *next;
} *CourseList;

bst.c

(not yet written)

courselist.c

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

void print_course_and_num_students(CourseList *self) {
CourseList current = *self;
while (current != NULL) 
{
    printf("%s\n", (current->data).name);
    current = current->next;
}
printf("\n");
}

void insert_course_at_front(CourseList *self, Course data) {
CourseList newNode = (CourseList)malloc(sizeof(struct courseNode));

if (*self == NULL)
{
    *self = newNode;
    (*self)->data = data;
    (*self)->next = NULL;
    return;
}

   newNode->data = data;
   newNode->next = *self;
   *self = newNode;
}

的main.c

#include <stdio.h>
#include "courselist.h"
#include "bst.h"
#include <stdlib.h>
#include <cstdbool>

#define MAX_LEN 100

void main()
{   
CourseList my_course = (CourseList)malloc(sizeof(struct courseNode));
my_course = NULL;
Course my_list;
(&my_list)->name = (char *)malloc(100 * sizeof(char));

bool program_quit = false;
int input_op;

char *insert_course_word;
insert_course_word = (char *)malloc(100 * sizeof(char));

char *delete_course_word;
delete_course_word = (char *)malloc(100 * sizeof(char));

do
{
    printf("Enter operation: ");
    scanf("%d", &input_op);

    switch (input_op)
    {
    case 0:            // Quit
        program_quit = true;
        break;

    case 1:            // Add Course
        program_quit = false;
        printf("Add Course: ");
        scanf("%s", (&my_list)->name);

        //(&my_list)->name = (insert_course_word);

        insert_course_at_front(&my_course, my_list);
        break;

    case 2:            // Remove Course
        program_quit = false;
        printf("Remove Course: ");
        scanf("%s", delete_course_word);
        (&my_list)->name = (delete_course_word);
        delete_course(&my_course, my_list);
        break;

    case 3:            // Enrol Student
        program_quit = false;
        break;

    case 4:            // Un-enrol student
        program_quit = false;
        break;

    case 5:            // Print a summary of courses and the number of students enrolled in each course
        program_quit = false;
        printf("Current enrolments:\n");
        print_course_and_num_students(&my_course);
        break;

    case 6:            // Print an ordered list of students enrolled in a course
        program_quit = false;
        break;

    case 7:            // Print a list of courses that a given student is enrolled in
        program_quit = false;
        break;

    default:
        printf("Invalid operation\n");
    }
} while (program_quit == false);

if (my_course != NULL)
{
    destroy(&my_course);
}

//destroy(&my_list);
return;
}

2 个答案:

答案 0 :(得分:1)

问题在于你永远不会创建一个新名称,而是所有课程结构&#39; name指针指向同一个内存区域,这是您在main开头分配的内存区域。

这应该这样做(waring未经测试):

program_quit = false;
printf("Add Course: ");
char* name = malloc(100 * sizeof(char));   
scanf("%s", name);    
my_list.name=name;
insert_course_at_front(&my_course, my_list);

但是,我会警告不要在与生产代码相关的任何内容中编写此类代码。如果用户输入超过100个字符,则内存损坏,如果输入较少,则会浪费内存。我认为在C(我很长时间没有编写生产质量的c代码)你通常会将输入字符逐个字符地读入本地缓冲区(当缓冲区已满时停止,或者你得到例如换行符)然后分配一个适当大小的内存块,最后将字符串复制到分配的内存块。

答案 1 :(得分:0)

更改

typedef struct course {
char *name;
BST students;
} Course;

typedef struct course {
char name[MAX_LEN];
BST students;
} Course;

有一些空间来放置名称

编辑 - 关于新信息

    Course new_course;
    new_course-> name = malloc(MAX_LEN);

    scanf("%s", new_course->name); // This could be better to prevent buffer overwrite
    insert_course_at_front(&my_course, new_course);