我在将数据添加到链接列表时遇到问题。这个代码基本上是尝试首先在结构中插入新的课程名称,然后将结构插入到链表中,并重复循环。用户有责任插入新的课程名称。
现在的问题是当用户使用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;
}
答案 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);