Reputation: 31
I have a problem in adding data into the linked list. This codes basically is trying to insert new course name into the struct first, then insert the struct into the linked list, and the cycle repeats. The user are responsible to insert the new course name.
The problem now is when user go to the add course operation using scanf, it always overwritten the existing course name in the linked list and add into it.
This is the input and output from the console application:
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:
(Changing h files is impossible as it is the requirement of the assignment from university)
Here are the c and h file attached below:
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;
}
Upvotes: 2
Views: 170
Reputation: 21166
The problem is that you never create a new name, but all course structures' name pointers point to the same memory region, which is the one you are allocating at the start of main
.
This should do it (waring untested):
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);
However, I would warn against writing such code in anything related to production code. If the user enters more than 100 characters, you get corrupted memory and if he enters less, you are wasting memory. I think in C
(i haven#t written production quality c-code in a long long time) you would usually read the input character by character into a local buffer (stopping when either the buffer si full, or you get e.g. a newline) and then allocate a chunk of memory of the appropriate size and finally copy the string to that allocated chunk of memory.
Upvotes: 1
Reputation: 60037
Change
typedef struct course {
char *name;
BST students;
} Course;
to
typedef struct course {
char name[MAX_LEN];
BST students;
} Course;
to have some space to place the name
EDIT - On new info
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);
Upvotes: 0