realloc struct of array inside function - c

I have made a library program to store movies in and using dynamic memory allocation for my struct array without success. Adding the first record (movie) works fine, but after the second the values are just messed up characters.
There is not really much more to say than showing my code.
The problem is that I can't realloc inside my function addmovie();
But if I put this line:
movie = (struct movies *) realloc(movie, (records+1) * sizeof(struct movies));
Right before calling addmovie(); function it seems to work, why?
/* Global variables */
int records = 0; // Number of records
struct movies{
char name[40];
int id;
};
addmovie(struct movies **movie)
{
int done = 1;
char again;
int index;
while (done)
{
index = records;
records++; // Increment total of records
struct movies *tmp = (struct movies *) realloc(movie, (records+1) * sizeof(struct movies));
if (tmp)
*movie = tmp;
system("cls");
fflush(stdin);
printf("Enter name of the Movie: ");
fgets(movie[index].name, 40, stdin);
fflush(stdin);
printf("Enter itemnumber of the Movie: ");
scanf("%d", &movie[index].id);
printf("\nSuccessfully added Movie record!\n");
printf("\nDo you want to add another Movie? (Y/N) ");
do
{
again = getch();
} while ( (again != 'y') && (again != 'n') );
switch ( again )
{
case ('y'):
break;
case ('n'):
done = 0;
break;
}
} // While
}
int main()
{
int choice;
struct movies *movie;
movie = (struct movies *) malloc(sizeof(struct movies)); // Dynamic memory, 68byte which is size of struct
while (done)
{
system("cls");
fflush(stdin);
choice = menu(); //returns value from menu
switch (choice)
{
case 1:
addmovie(movie);
break;
}
} // While
free(movie); // Free allocated memory
return 0;
}

C is a pass-by-value language. When you do:
movie = (struct movies *) realloc(movie, (records+1) * sizeof(struct movies));
In your function, movie from main() isn't affected at all. You need to pass a pointer-to-a-pointer:
void addmovie(struct movies **movie)
and then modify the pointer's contents:
struct movies *tmp = realloc(...)
if (tmp)
*movies = tmp;
Note that it's also important not to assign the return value of realloc back to the variable to passed to it - you might end up leaking.
Check the comp.lang.c FAQ question 4.8 for a complete explanation.

Related

Dynamically allocated memory in structure in c

I'm trying to create two lists, pros and cons and then print them.
But I can't figure out what am I doing wrong.
I tried to debug the program with gdb online and I found out that the error is in function fgets().
#include <stdio.h>
#include <string.h>
typedef struct list{
char ** reason;
} list;
void printMenu();
void printList(list * myList, int len1);
int main(void)
{
int keepGoing = 0;
int choice = 0;
int i = 0;
int j = 0;
list * pros;
list * cons;
while (!keepGoing){
printMenu();
scanf("%d", &choice);
pros = (list*)malloc(sizeof(list));
cons = (list*)malloc(sizeof(list));
switch (choice){
case 1:
i++;
printf("Enter a reason to add to list PRO: ");
pros = (list*)realloc(pros, i*sizeof(list));
fgets(pros->reason[i], 50, stdin);
pros->reason[strcspn(pros->reason[i], "\n")] = 0;
break;
case 2:
j++;
cons = (list*)realloc(cons->reason, j*sizeof(list));
printf("Enter a reason to add to list CON: ");
fgets(cons->reason[j], 50, stdin);
cons->reason[strcspn(cons->reason[j], "\n")] = 0;
break;
case 3:
printf("PROS:\n");
printList(pros, i);
printf("CONS:\n");
printList(cons, j);
break;
case 4:
keepGoing = 1;
break;
default:
printf("Invalid value.");
keepGoing = 1;
}
}
free(pros);
free(cons);
getchar();
return 0;
}
void printList(list * reasons, int len1){
int i = 0;
for (i = 0; i < len1; i++){
printf("%s\n", reasons->reason[i]);
}
}
void printMenu(){
printf("Choose option:\n");
printf("1 - Add PRO reason\n");
printf("2 - Add CON reason\n");
printf("3 - Print reasons\n");
printf("4 - Exit\n");
}
There is no need to allocate these dynamically: list * pros; list * cons;. Code like pros = (list*)realloc(pros, i*sizeof(list)); doesn't make any sense.
Instead, declare them as plain variables. list pros.
What you instead need to allocate dynamically is the member pros.reason. You need to allocate an array of pointers that it points to, and then you need to allocate the individual arrays.
You have a problem in
fgets(pros->reason[i], 50, stdin);
as the memory you want to use is not valid. pros->reason does not point to a valid memory, so you cannot dereference it, this causes undefined behavior.
Before you can index-into pros->reason, you need to make pros->reason point to a valid memory location.
After that, you need to make pros->reason[i]s also to point to valid memory if you want them to be used as the destination of fgets().
Apart from this issue, you have another issue which makes this code nonsense, that is calling malloc() on every iteration of the loop. You need to call malloc() only once, to get a pointer (to memory) allocated by memory allocator function and then, use realloc() inside the loop to adjust that to the required memory.
There are many issues. Previous comments and answers do still apply.
Here is a clean solution.
The list structure is now self contained, no need to track the number of strings in separate variables
added selfcontained AddString function
no more unnecessary mallocs
all allocated memory is freed correctly
some logic errors removed (inverted logic of keepGoing)
There is still room for improvement. Especially there is no error checking for the memory allocation functions.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct list {
int size; // number of strings
int chunksize; // current of chunk
char ** reason;
} list;
void printMenu();
void printList(list * reasons);
void freeList(list * l);
void AddString(list *l, const char *string);
int main(void)
{
int keepGoing = 1;
int choice = 0;
list pros = { 0 }; // = {0} initializes all fields to 0
list cons = { 0 };
while (keepGoing) {
printMenu();
scanf("%d", &choice);
char input[50];
fgets(input, sizeof(input), stdin); // absorb \n from scanf
switch (choice) {
case 1:
printf("Enter a reason to add to list PRO: ");
fgets(input, sizeof(input), stdin);
AddString(&pros, input); // Add string to pros
break;
case 2:
printf("Enter a reason to add to list CONS: ");
fgets(input, sizeof(input), stdin);
AddString(&cons, input); // Add string to cons
break;
case 3:
printf("PROS:\n");
printList(&pros);
printf("CONS:\n");
printList(&cons);
break;
case 4:
keepGoing = 0;
break;
default:
printf("Invalid value.");
keepGoing = 1;
}
}
freeList(&pros);
freeList(&cons);
getchar();
return 0;
}
#define CHUNKSIZE 10
void AddString(list *l, const char *string)
{
if (l->size == l->chunksize)
{
// resize the reason pointer every CHUNKSIZE entries
l->chunksize = (l->chunksize + CHUNKSIZE);
// Initially l->reason is NULL and it's OK to realloc a NULL pointer
l->reason = realloc(l->reason, sizeof(char**) * l->chunksize);
}
// allocate memory for string (+1 for NUL terminator)
l->reason[l->size] = malloc(strlen(string) + 1);
// copy the string to newly allocated memory
strcpy(l->reason[l->size], string);
// increase number of strings
l->size++;
}
void freeList(list * l) {
for (int i = 0; i < l->size; i++) {
// free string
free(l->reason[i]);
}
// free the list of pointers
free(l->reason);
}
void printList(list * l) {
for (int i = 0; i < l->size; i++) {
printf("%s\n", l->reason[i]);
}
}
void printMenu() {
printf("Choose option:\n");
printf("1 - Add PRO reason\n");
printf("2 - Add CON reason\n");
printf("3 - Print reasons\n");
printf("4 - Exit\n");
}

allocating in heap memory array of pointers to struct

I'm trying to make simple data base by using structure like
struct Employee{
char* name;
int ID;
int GPA;
int salary;
};
i know how i can allocate one pointer of the struct type in heap by using that
struct Employee* emp=malloc(sizeof(Employee));
my problem now that i'm not very good in allocating processes and i want
to allocate N number of pointer of the struct in the heap and i can't use arrays because the size will not be knows until running time
any suggestions ?
Yes, you need to allocate the memory dynamically, i.e. allocate a new heap block for every new struct Employee.
You can do this for example using realloc when the size changes:
yourArrayPtr=realloc(yourArrayPtr,newsize * sizeof(struct Employee));
The realloc function basically assigns a new amount of memory for the data pointed by its return value. It is a convenient way of expanding, or shrinking a dynamically allocated array. newsize here is the new number of elements of your array, and it is multiplied by the size of one Employee structure, rendering the total amount of space needed for your new array. The return value of realloc is assigned to your array pointer, so that it points specifically to this newly allocated space. In this case it could be used like this:
struct Employee* emp= NULL;
And then when you need it:
int n = 8;
emp = realloc (emp, n * sizeof(struct Employee));
Keep in mind, that you still have to free this memory.
You can now initialize and access this data:
emp[3] = {value1, value2, value3, ...};
As far as structures go, you could also think of another data structure - a linked list, where every structure contains a pointer to its successor. You can read about it here: http://www.cprogramming.com/tutorial/c/lesson15.html
In your case, it would be sth like:
struct Employee{
char* data;
struct Employee* next;
};
As others mentioned, you can use malloc to create as many entries of employee details in heap and store them in a dynamic list(linked list). i have given an example code, you can start from here and extend it, if you want to save the employee details before exiting, you can write it to a binary file and read it back when you run the program again(based on your needs), since once you program exits all the data will be lost.
#include <stdio.h>
#include <stdlib.h>
// Max length for employee name
const unsigned int MAX_NAME_LEN = 100;
typedef struct Employee{
char* name;
unsigned int ID;
int GPA;
float salary;
} EMPLOYEE ;
typedef struct emp_database_entry {
EMPLOYEE data;
struct emp_database_entry *next;
} EMPLOYEE_ENTRY;
typedef EMPLOYEE_ENTRY* EMPLOYEE_DATABASE;
// to create a new employee
EMPLOYEE_ENTRY* createEmployee() {
EMPLOYEE_ENTRY *newEmp = (EMPLOYEE_ENTRY*)malloc(sizeof(EMPLOYEE_ENTRY));
printf("Enter Employee Name:");
newEmp->data.name = (char*)malloc( MAX_NAME_LEN * sizeof(char) );
scanf("%s",newEmp->data.name);
printf("Enter employee ID:");
scanf("%u",&newEmp->data.ID);
printf("Enter employee GPA:");
scanf("%u",&newEmp->data.GPA);
printf("Enter employee salary:");
scanf("%f",&newEmp->data.salary);
newEmp->next = 0;
return (newEmp);
}
// add a new employee to database
EMPLOYEE_DATABASE addEmployee(EMPLOYEE_DATABASE db) {
EMPLOYEE_ENTRY *newEmp = createEmployee();
if(db == NULL) {
// add the first entry
db = newEmp;
} else {
// add it to the top
newEmp->next = db;
db = newEmp;
}
return (db);
}
// Search for Employee using ID
EMPLOYEE_ENTRY* searchEmployee(EMPLOYEE_DATABASE db, unsigned int ID) {
EMPLOYEE_ENTRY *employee = db;
if(employee == NULL) {
printf("There are no Employees in the database\n");
return (NULL);
}
// Search till the end, if a match is found return the
// pointer to employee
while( employee != NULL ) {
if( employee->data.ID == ID )
return (employee);
else
employee = employee->next;
}
return (NULL);
}
void printOneEmployee( EMPLOYEE_ENTRY *employee ) {
printf("Employee Details\n");
printf("Name : %s\n",employee->data.name);
printf("ID : %u\n",employee->data.ID);
printf("GPA : %d\n",employee->data.GPA);
printf("Salary: %f\n\n",employee->data.salary);
}
// Print all employee details
void printAllEmployee( EMPLOYEE_DATABASE db ) {
EMPLOYEE_ENTRY *employee = db;
// traverse till the end and print one by one
while( employee != NULL ) {
printOneEmployee(employee);
employee = employee->next;
}
}
// freeing allocated memory
void freeDatabase(EMPLOYEE_DATABASE db) {
EMPLOYEE_DATABASE employee = 0;
while( db != NULL ) {
employee = db;
db = employee->next;
free(employee->data.name);
free(employee);
}
}
void displayOption( EMPLOYEE_DATABASE db ) {
int option = -1;
while( option != 5 ) {
printf("\nEmployee DataBase\n");
printf("1: Add a Employee\n");
printf("2: Search Employee\n");
printf("3: Print All Employee\n");
printf("4: Exit\n");
printf("Enter a number for the choice: ");
scanf("%d",&option);
if( option > 4 || option < 0 ) {
option = -1;
}
switch( option ) {
case 1:
db = addEmployee(db);
break;
case 2:
int ID;
if(db != NULL){
printf("Enter the Employee ID: ");
scanf("%d",&ID);
printf("Search Result1: ");
printOneEmployee(searchEmployee(db, ID));
}
else
printf("No Employees in the database\n");
break;
case 3:
printAllEmployee(db);
break;
case 4:
freeDatabase(db);
printf("DataBase Deleted\nExiting..");
exit(0);
default:
printf("Invalid Option!. Try Again!.\n");
}
}
}
int main() {
EMPLOYEE_DATABASE db = 0;
displayOption(db);
return (0);
}
Of course you can use arrays if you use C99. In C99 you can do things like:
scanf("%d", &N);
struct Employee emp[N];
emp[0].ID = 123;
if you are using gcc (or MinGW), just be sure to compile with -std=c99
On the other hand, if you just want to create an array on the heap, you can do something like:
scanf("%d", &N);
struct Employee* emp=malloc(N*sizeof(Employee));
emp[0].ID =123;
...
// do not forget to deallocate emp
free(emp);

Adding records with pointers to arrays

I have to create a program which adds records to a simple phone book. The code is below, but it doesn't work - function ends and then it stucks on declaring struct record x and doesn't want to display my added record - the program breaks down. When I put this part of code on the end of the function (but instead of "struct record x = array[0];" I put "struct record x = (*array)[0]") it works - record is printed. So I guess the problem is something about pointers, but I'm struggling and I really couldn't find out what's wrong. I remember that few weeks ago I created a program which was very similar but it was adding a new record to an array of integers, with fixed values and it was working well, so maybe there's something with structures that I don't know about. Thanks for any help!
I know the program isn't done yet and I know that I didn't make any action for temp_array == NULL, it'll be done after I found out what's going on.
struct record {
char f_name[SIZE];
char name[SIZE];
long int phone;
};
int add_record(struct record** array, int n)
{
struct record* temp_array = malloc((n+1) * sizeof(struct record));
if (temp_array == NULL)
{
free(temp_array);
return -1;
}
int i;
for (i=0; i < n; i++)
{
temp_array[i] = (*array)[i];
}
struct record new_record;
printf("\nAplly data.");
printf("\nFirst name: "); /*fgets(new_record.f_name, SIZE, stdin);*/ scanf("%s", &new_record.f_name);
printf("Surname: "); /*fgets(new_record.name, SIZE, stdin);*/ scanf("%s", &new_record.name);
printf("Phone number: "); scanf("%d", &new_record.phone);
temp_array[n] = new_record;
free (*array);
*array = temp_array;
//struct record x = (*array)[0];
//puts(x.f_name); puts(x.name); printf("%d", x.phone);
return 0;
}
main()
{
struct record* array; int n = 0;
int choice;
printf("\n1. Add record\n2. Delete record\n3. Find record\n0. Exit\n\nChoose action: ");
scanf("%d", &choice);
switch(choice) {
case 0: printf("\nKsiazka zostala zamknieta.\n"); return;
case 1: add_record(&array, n); n++; break;
case 2: return;
case 3: return;
default: printf("Wrong choice.\n\n"); return;
}
struct record x = array[0];
puts(x.f_name); puts(x.name); printf("%d", x.phone);
}
struct record* array=NULL;, and use %ld for long int – BLUEPIXY

ATP list in C, reading and saving usernames

I have a problem writing a code that should read usernames and put them in list. Every username should be connected to the number of times it has been entered. The problem occurs when entering the second username, my code places that username in the variable called first (where the first is kept). I guess I've done something wrong with the pointers, but I cannot find what. I am confused, in the end of one while loop the first one is the real first one, and when the program enters while again, variable first changes. How could that be? Please help me.
Thank you :)
typedef struct _user
{
char *name;
int counter;
struct _user *next;
} user;
int main() {
char userName [10];
int found = 0, go_on = 1;
user *first = NULL, *temp, *new;
while (go_on == 1) {
printf ("Username: ");
scanf("%s", userName);
if (first) {
// printf ("The first one in list: %s\n", first->name); - this prints the name of last username entered
for (temp = first; temp; temp = temp->next) {
if (strcmp (temp->name, userName) == 0) {
temp->counter++;
found = 1; }
if (found== 1) break;}
if (!found) {
new = (user*) malloc (sizeof(user));
new->name = userName;
new->counter = 1;
temp = new;
temp->next = NULL; } }
else {
new = (user*) malloc (sizeof(user));
new->name = userName;
new->counter = 1;
first = new;
first->next = NULL; }
printf ("Go on? (1/0)");
scanf("%d", &go_on);
printf ("Current list: ");
for (temp=first; temp; temp = temp->next)
printf("%s %d\n", temp->name, temp->counter);
//printf ("The first one in list: %s\n", first->name); - this prints the correct first
}
}
Your error, I think, is the userName array. You should allocate a new one for each element in your linked list. When you write new->name = userName;, you are not copying the name to the struct, you are making the struct point to your userName[10] array. As such every struct's actual "name" is storing only the single last name scanf-ed. That being said...
I generally prefer to write that kind of code with dedicated tools instead of logically embedding them in a loop construct:
Keeping your struct:
typedef struct _user
{
char *name;
int counter;
struct _user *next;
} user;
I would create a function that, given a properly constructed Sll returns a matching element:
function user *user_match_name(user *user_head, const ch *name)
{
user *cur_user = NULL;
/* look for a match */
for (cur_user = user_head ; cur_user ; cur_user = cur_user->next)
if(!strcmp(name,cur_user->name) return cur_user;
/* no match */
return NULL;
}
Then I usually prefer to have an Sll element builder:
function user *create_user(const ch *name)
{
user *new_user;
if(!(new_user = malloc(sizeof(user))))
printf("Error in allocation"); /* or better malloc error handling */
/* IMPORTANT: PROVIDE MEMORY FOR THE NAMES!!! */
if(!(new_user->name = malloc(sizeof(char)*256))) /* sizeof(char) is useless but I like to explicit it like that. And 256 should be enough a buffer could be better made */
printf("Error in allocation"); /* or better malloc error handling */
strncpy(new_user->name, name,256); /* not sure if I got the argument order right... */
new_user->counter = 0; /* or 1 depending on your prefered convention */
new_user->next = NULL;
return new_user;
}
It ease the debugging like you wouldn't believe! Then it's just a matter of rewriting your main function:
int main() {
char userName [10];
int found = 0, go_on = 1;
user *user_head = NULL, *new_user,*temp;
while (go_on == 1) {
printf ("Username: ");
scanf("%s", userName);
if( (new_user = user_match_name(user_head,userName)) )
++new_user->counter
else
new_user = create_user(userName);
/* Here we push on the Sll */
if(user_head){
new_user->next = user_head;
user_head = new_user;
} else {
user_head = new_user;
}
printf ("Go on? (1/0)");
scanf("%d", &go_on);
printf ("Current list: ");
for (temp = user_head; temp; temp = temp->next)
printf("%s %d\n", temp->name, temp->counter);
//printf ("The first one in list: %s\n", first->name); - this prints the correct first
}
}
Ahhhhhh! Much easier to read. Be mindful of: 1) I didn't compile check the code. The important ideas are there, leverage them. 2) Even in your previous implementation, you are white space vulnerable but that's somewhat another topic.
Or you could cimply fix it by doing:
typedef struct _user
{
char name[10];
int counter;
struct _user *next;
} user;
and strncpy(new->name,userName,10) instead of assigning the pointer.

Creating array of structure

I have been busy with a question from a C book. The question is simple but it has some specific parts.
I would like to ask a question about arrays.
My question is about the best way with creating an array of a structure. The question wants these all;
Firstly create an array of structure. Secondly, create a linked list which connects these arrays with a restp pointer.
I want to divide my question into sub parts. First part is array of structure...
How can I create an array of a structure. I've made a research about this. And here is my way:
I'm creating a structure for my array of structure:
struct student{
int id;
struct courseList_node_s *restp;
};
And my linked list for completing rest of question:
typedef struct courseList_node_s{
char course[6];
int credit,
section;
struct courseList_node_s *restp;
}courseList_node_t;
I have implemented some function to handle this student schedule.
In my get_studentList function;
I declared my array as this;
struct student *ansp[size];
And making memory allocation;
ansp[i] = malloc(sizeof(struct student));
And lastly assigning a value;
ansp[i]->id =id;
Now, my problem is while creating an array, I couldn't make it as an ordered array. For instance, the user can type 1111, 1222, 1232, and then 1011. So, my first element of array which is ansp[0] = 1011, and ansp[1] = 1111.
I couldn't figure out.
Can you give me an algorithm which consist these(Creating an ordered array of structure).
Lastly, sorry for my bad English and I may made some grammatical mistakes...
Thanks in advance.
To order the elements, you will need to sort them. In C, you probably want to use qsort (in C++ there are easier ways). You will need to define a comparison function on struct student * and call qsort on your array with it.
See this example for inspiration. Note that your array is an array of structure pointers, the example is an array of direct structures (which is maybe what you wanted anyway?).
Can you give me an algorithm which consist these(Creating an ordered array of structure).
If you want to create an orderd array of structures, you probably want to build a tree.
There are libraries for that, but to learn and understand, you can Google 'Binary trees in C' or something like that, e.g.:
http://www.macs.hw.ac.uk/~rjp/Coursewww/Cwww/tree.html
Trees will allow your user to insert non-sorted values and retrieve them in sorted order (also, search them more quickly).
I'd solved the problem with helps #Keith Randall and
lserni
I have implemented both binary search tree and array of structure.
First way, sorting array with qsort:
I had to create a compare function:
int compare(const void *p1, const void *p2){
return (* (struct student **) p1)->id - (* (struct student **) p2)->id;
}
And my other helper functions;
void get_studentList(struct student **listp,int size){
int id,i;
struct student *ansp[size];
for(i=0;i<size;i++){
printf("Enter student's id to exit enter -1> ");
scanf("%d", &id);
ansp[i] = malloc(sizeof(courseList_node_t));
ansp[i]->id = id;
ansp[i]->restp = NULL;
}
qsort (ansp, size, sizeof(struct student *), compare);
for(i=0;i<size;i++){
listp[i] = ansp[i];
}
}
courseList_node_t * insert_studentSchedule(courseList_node_t *headp, int size){
courseList_node_t *cur_nodep;
if(headp == NULL){
cur_nodep = scan_course();
headp = cur_nodep;
} else {
headp->restp = insert_studentSchedule(headp->restp,size);
}
return (headp);
}
And my display function;
void display_schedule(struct student **headp, int size){
courseList_node_t *cur_nodep;
int i = 0;
while(i< size){
cur_nodep = headp[i]->restp;
printf("Student id > %d\n", headp[i]->id);
while(cur_nodep != NULL){
printf("Course name> %s\t", cur_nodep->course);
printf("Course credit> %d\t", cur_nodep->credit);
printf("Course section> %d\n", cur_nodep->section);
cur_nodep = cur_nodep->restp;
}
i++;
}
}
Second way, Binary Search Tree:
I changed typedef parts of my header file as this:
typedef struct tree_node_s{
int id;
struct courseList_node_s *restp;
struct tree_node_s *leftp, *rightp;
}tree_node_t;
And my macro to formalize a standart pattern in dynamic allocation of nodes:
#define TYPED_ALLOC(type) (type *)malloc(sizeof(type))
And my implementation of creating a binary search tree:
/*
* Insert a new id in a binary search tree.
* Pre: rootp points to the root node of a binary search tree
*/
tree_node_t * get_studentTree(tree_node_t *rootp, int newId)
{
if (rootp == NULL){
rootp = TYPED_ALLOC(tree_node_t);
rootp->id = newId;
rootp->restp = NULL;
rootp->leftp = NULL;
rootp->rightp = NULL;
} else if ( newId == rootp->id){
/* */
} else if (newId < rootp->id){
rootp->leftp = get_studentTree(rootp->leftp, newId);
} else {
rootp->rightp = get_studentTree(rootp->rightp, newId);
}
return (rootp);
}
This parts are not related with this question. I gave them because I want to share the partial solution of real question.
/*
* Its aim to add courses to restp component of subtree
* It may have some problems. And you can omit it. Because it not related with this question
* Pre: elementp not empty
*/
courseList_node_t * add_course(courseList_node_t *nextp, courseList_node_t *elementp){
if(nextp->restp == NULL){
nextp->restp = elementp;
} else {
nextp->restp = add_course(nextp->restp,elementp);
}
return (nextp);
}
/*
* It is not neccessary to first call get_studentTree function. It simply creates a linked list which consist of student class/lecture schedule.
* Pre: ele and id not empty
* Post: Tree returned includes all schedule and retains binary search tree properties.
*/
tree_node_t * insert_studentSchedule(tree_node_t *rootp,courseList_node_t *ele, int id){
if (rootp == NULL){
rootp = get_studentTree(rootp, id);
rootp->restp = TYPED_ALLOC(courseList_node_t);
strcpy(rootp->restp->course, ele->course);
rootp->restp->credit = ele->credit;
rootp->restp->section = ele->section;
}
else if(rootp->id == id){
if ( rootp->restp == NULL ){
rootp->restp = TYPED_ALLOC(courseList_node_t);
strcpy(rootp->restp->course, ele->course);
rootp->restp->credit = ele->credit;
rootp->restp->section = ele->section;
} else {
rootp->restp = add_course(rootp->restp, ele);
}
} else if ( id < rootp->id ){
if ( rootp->leftp != NULL )
rootp->leftp = insert_studentSchedule(rootp->leftp, ele, id);
} else if ( id > rootp->id ) {
if ( rootp->rightp != NULL )
rootp->rightp = insert_studentSchedule(rootp->rightp, ele, id);
}
return (rootp);
}
/*
* Course scanning function
*/
courseList_node_t * scan_course(void){
courseList_node_t *cur_coursep;
char courseName[6];
cur_coursep = (courseList_node_t *)malloc(sizeof(courseList_node_t));
printf("Welcome to course scanning part>\n");
printf("Enter the name of course> ");
scanf("%s", courseName);
strcpy(cur_coursep->course, courseName);
printf("Enter the credit of course> ");
scanf("%d", &cur_coursep->credit);
printf("Enter the section of course> ");
scanf("%d", &cur_coursep->section);
cur_coursep->restp = NULL;
return (cur_coursep);
}
/*
* My way to print binary search tree with all elements
*/
void display_schedule(tree_node_t *rootp){
courseList_node_t *cur_course;
if(rootp == NULL)
return;
display_schedule(rootp->leftp);
if (rootp->restp == NULL)
printf("Tree with id: %d element has no member!", rootp->id);
else {
cur_course = rootp->restp;
while (cur_course != NULL){
printf("Student Id> %d\n", rootp->id);
printf("Course name> %s\t", rootp->restp->course);
printf("Course credit> %d\t", rootp->restp->credit);
printf("Course section> %d\n", rootp->restp->section);
cur_course = cur_course->restp;
}
}
display_schedule(rootp->rightp);
}
It may not full solution of book question but with your helps, It is solution of essential parts. If you found a mistake. Feel free to add a comment.

Resources