C programming
Implement a function called ReadLine() in driver1.c
Then modify the driver program (driver1.c) such that it can interact with the user to get many students' information (id, gpa, and name) and manage the linked list by using the structures and functions from mylinkedlist library. Specifically, your driver program will create/initilize a linked list, e.g., list = NewLinkedList(); and then ask user what to do in a loop as follows:
1 - Create a new student cell with given id, gpa, name info, and add (Enlist) it to the end of the linked list
2 - Remove (Delist) the first student from linked list and print his/her id, gpa, name info
3 - Print the number of students in the linked list (Length)
4 - Print (id, gpa, name) of a students at a specific index (head of the list is defined as index 0)
5 - Print (id, gpa, name) of every student in the linked list
6 - Print the min, average, max gpa in the linked list
7 - Remove the student with highest gpa and print his/her info
8 - Exit
Enter your choice:
(depending on choice enter additional info, e.g., id, gpa, name, index)
If the user selects 1, your program should ask user to also enter a student's id (an integer), gpa (a double), name (char *); then create a new student cell with these parameters, e.g., element = NewStudentCell(id, gpa, name); and insert element at the end of the linked list using Enlist(list, element);.
When reading id (an integer) and gpa (a double) you can simply use standard library functions (e.g., scanf("%d", &id). However, when reading name (char *), you need to use the new function (e.g., name = ReadLine();) mentioned in Part 1. More information about this function is in driver1.c.
If the user selects 2, your program should remove the first cell from the linked list, e.g., element = Delist(list); print the information of element, and free it.
If the user selects 3, your program should find the number of students in the linked list, e.g., n = LinkedListLength(list) and print n.
If the user selects 4, your program should ask user to also enter an index, then find the cell at that index using element = GetLinkedListElement(list, index); print the information of element. Note that the element is still in the list, it is not removed. We just look at the information at that index!
If the user selects 5, your program should go over each cell in the linked list, and print the information from that cell.
If the user selects 6, your program should go over each cell in the linked list, and compute the min, average, mag gpa, and print them.
If the user selects 7, your program should search the cell with maximum gpa, then remove it from the linked list, print the information from that cell, and free it.
If the user selects 8, your program should stop the loop. Then free all the cells, linked list, and names. Finally, quit. Use valgrind to make sure there is no memory leakage.
YOU WOULD NEED TO IMPLEMENT NEW FUNCTIONS FOR THE TASKS IN OPTIONS 5, 6, 7, and 8.
driver1.c
#include
#include
#include "mylinkedlist.h"
char *ReadLine(void);
int main(int argc, char *arvg[])
{
// YOU NEED TO IMPLEMENT THIS driver1.c USING FUNCTIONS FROM mylinkedlist.h
// But before that, implement your ReadLine() function, and test it as shown below.
// IF NEEDED, YOU CAN ALSO IMLEMENT YOUR OWN FUNCTIONS HERE
char *name;
printf("Enter a name to test your ReadLine function : ");
name = ReadLine();
printf("User entered : %s ", name);
free(name);
return 0;
}
char *ReadLine()
{
// A SIMPLE WAY TO IMPLEMENT JUST TO TEST FOR NOW, BUT THIS IS NOT WHAT WE WANT!!!
char *buff = malloc(100);
scanf("%s", buff);
return buff;
// YOU NEED TO DELETE ABOVE 3 LINES, and IMPLEMENT THSI as described above
return(NULL); // if there is any error!
}
mylinkedlist.c
#include
#include
#include "mylinkedlist.h"
student_cell_T *NewStudentCell(int id, double gpa, char *name)
{
student_cell_T *element;
element = (student_cell_T *) malloc( sizeof(student_cell_T) );
if( !element){
fprintf(stderr,"NewStudentCell cannot allocate memory ");
return NULL;
}
element->id = id;
element->gpa = gpa;
element->name = name;
return element;
}
linked_list_T *NewLinkedList(void)
{
linked_list_T *list;
list = (linked_list_T *) malloc( sizeof(linked_list_T) );
if( !list){
fprintf(stderr,"NewLinkedList cannot allocate memory ");
return NULL;
}
list->head = NULL;
list->tail = NULL;
return list;
}
void FreeLinkedList(linked_list_T *list)
{}
void Enlist(linked_list_T *list, student_cell_T *element)
{}
student_cell_T *Delist(linked_list_T *list)
{}
int LinkedListIsEmpty(linked_list_T *list)
{}
int LinkedListIsFull(linked_list_T *list)
{
return 0; // because we have linked list
}
int LinkedListLength(linked_list_T *list)
{}
student_cell_T *GetLinkedListElement(linked_list_T *list, int index)
{}
mylinkedlist.h
#ifndef _mylinkedlist_h
#define _mylinkedlist_h
typedef struct student_cell_T {
int id;
double gpa;
char *name; // name is just a pointer here, you need to allocate space for name
struct student_cell_T *next;
} student_cell_T;
typedef struct linked_list_T {
student_cell_T *head;
student_cell_T *tail;
} linked_list_T;
student_cell_T *NewStudentCell(int id, double gpa, char *name);
linked_list_T *NewLinkedList(void);
void FreeLinkedList(linked_list_T *list);
void Enlist(linked_list_T *list, student_cell_T *element);
student_cell_T *Delist(linked_list_T *list);
int LinkedListIsEmpty(linked_list_T *list);
int LinkedListIsFull(linked_list_T *list);
int LinkedListLength(linked_list_T *list);
student_cell_T *GetLinkedListElement(linked_list_T *list, int index);
#endif
makefile
CC = gcc CFLAGS = -Wall -g
all: driver1
clean: rm -f *.o driver1
mylinkedlist.o: mylinkedlist.c mylinkedlist.h $(CC) $(CFLAGS) -c mylinkedlist.c
driver1.o: driver1.c mylinkedlist.h $(CC) $(CFLAGS) -c driver1.c
driver1: driver1.o mylinkedlist.o $(CC) $(CFLAGS) -o driver1 driver1.o mylinkedlist.o
#include
#include #include "mylinkedlist.h" Function: ReadLine Usage: s = ReadLine(); ReadLine reads a line of text from standard input and returns * the line as a string. The newline ' ' character that terminates * the input is not stored as part of the string. */ char *ReadLine(void); int main(int argc, char *arvg[]) { // YOU NEED TO IMPLEMENT THIS driver1.c USING FUNCTIONS FROM mylinkedlist.h // But before that, implement your ReadLine() function, and test it as shown below. // IF NEEDED, YOU CAN ALSO IMLEMENT YOUR OWN FUNCTIONS HERE char *name; : "); printf("Enter a name to test your ReadLine function name = ReadLine(); printf("User entered : %s ", name); free (name); return 0; } * * IMPLEMENTATION of ReadLine(); * Function: ReadLine * Usage: s = ReadLine(); * ReadLine reads a line of text from standard input and returns the line as a string. The newline ' ' character that terminates the input is not stored as part of the string. In contrast to standard I/O functions (e.g., scanf with "5", fgets) that can read strings into a given static size buffer, ReadLine function * should read the given input line of characters terminated by a newline * character (' ') into a dynamically allocated and resized buffer based on the length of the given input line. * When implementing this function you can use standard I/O functions. We just want you to make sure you allocate enough space for the entered data. * So don't simply allocate 100 or 1000 bytes every time. * If the given input has 5 characters, you need to allocate space for 6 characters. * Hint: initially dynamically allocate an array of char with size 10. Then, read data into that array character by charecter (e.g, you can use getchar()). If you see ' ' char before reading 10th character, you are done. And you know the * exact length of the input string. So, accordingly allocate enough space and copy the data into new char array, insert '10' instead of ' ' and free the original array. * Then return the new string. However, if you DO NOT see ' ' char after 10th character, * then you need larger space. Accordingly, resize your original array and double its size * and continue reading data character by character as in the first step... Hope you got the idea! Also please check for possible errors (e.g., no memory etc.) and appropriately handle them. For example, if malloc returns NULL, free partially allocated space and return NULL from this function. The program calling this function may take other actions, e.g., stop the program! */ char *ReadLine() { // A SIMPLE WAY TO IMPLEMENT JUST TO TEST FOR NOW, BUT THIS IS NOT WHAT WE WANT!!! char *buff = malloc(100); scanf("%s", buff); return buff; // YOU NEED TO DELETE ABOVE 3 LINES, and IMPLEMENT THSI as described above return(NULL); // if there is any error! } #include #include #include "mylinkedlist.h" * Function: NewStudentCell * Usage: student_cell_t *element; element = NewStudentCell(int id, double gpa, char *name); This function allocates space for a student cell and intilize its fileds student_cell_t *NewStudentCell(int id, double gpa, char *name) student_cell_t *element; element = (student_cell_t *) malloc( sizeof(student_cell_T) ); if( !element) { fprintf(stderr, "NewStudentCell cannot allocate memory "); return NULL; element->id = id; element->gpa = gpa; element->name = name; return element; } /* Function: NewLinkedList Usage: linked_list_T *list; list = NewLinkedList(); This function allocates and returns an empty linked list. */ linked_list_T *NewLinkedList(void) { linked_list_T *list; list = (linked_list_T *) malloc( sizeof(linked_list_T) ); if( !list) { fprintf(stderr, "NewLinkedList cannot allocate memory "); return NULL; } list->head = NULL; list->tail = NULL; return list; } * * Function: FreeLinkedList Usage: FreeLinkedList(list); This function frees the storage associated with list. */ void FreeLinkedList(linked_list_T *list) { } * Function: Enlist Usage: Enlist(list, element); This function adds a student cell pointed by element to the end of the list. */ void Enlist(linked_list_t *list, student_cell_T *element) { } /* * Function: Delist Usage: element = Delist(list); * This function removes the student cell at the head of the list * and returns its address to the caller (client). If the list is empty, Delist * prints an Error with an appropriate message and returns NULL. student_cell_T *Delist(linked_list_T *list) { } * ** * Functions: LinkedListIsEmpty, LinkedListIsFull * Usage: if (LinkedListIsEmpty(list)) ... if (LinkedListIsFull(list)) ... * These functions test whether the list is empty or full. */ int LinkedListIsEmpty(linked_list_T *list) { } int LinkedListIsFull(linked_list_T *list) { return 0; // because we have linked list ** * Function: LinkedListLength * Usage: n = LinkedListLength(list); * This function returns the number of elements in the list. int LinkedListLength(linked_list_t *list) { } ** * Function: GetLinkedListElement * Usage: element = GetLinkedListElement(list, index); * This function returns the element at the specified index in the * list, where the head of the list is defined as index 0. For * example, calling GetLinkedListElement(list, 0) returns the initial * element from the list without removing it. If the caller tries * to select an element that is out of range, GetLinkedListElement prints * Error and returns NULL. Note: This function is not a fundamental list operation * and is instead provided mainly to facilitate debugging. */ student_cell_T *GetLinkedListElement(linked_list_T *list, int index) { } /* OTHER FUNCTIONS YOU WOULD NEED.... * EXPORT THEM HERE, BUT IMPLMENT THEM in mylinkedlist.c */ sifndef _mylinkedlist_h sdefine _mylinkedlist_h * Type: student cell * This type defines the cells used for the linked list that * stores the student information we use in assinge * You can change this structure later on for other assignments! typedef struct student_cell_T int 1d; double gpa; char .. *name: // name is just a pointer here, you need to allocate space for name struct student_cell_t *next; ) student_cellT * Type: linked list T * This type defines the concrete representation of a linked list of student cells. *The head field points to the first element in the linked list. * The tail field points to the last element in the linked list. * The empty linked list is indicated by a NULL head pointer. typedef struct linked_list_T{ student cell.T *head; student_cell_t *tail; } linked_list_T; * Function: NewStudentcell * Usage: student cell T element: * element = NewStudentcell(id, gpa, nane); This function allocates space for a student cell and intilize its fileds student_cell_T *NewStudentCell(int id, double gpa, char sname); * Function: NewLinkedlist Usage: linked_list_T *list; list - NewLinkedList: * This function allocates and returns an empty linked list. linked_list_T NewLinkedList(void); * Function: FreeLinkedList * Usage: FreeLinkedList(list); *This function frees the storage associated with list. void FreeLinkedList(linked_list_T slist); * Function: Enlist * Usage: Enlistilist, element); * This function adds a student cell pointed by element to the end of the list. * void Enlist (linked_list_t *list, student_cell_t *element); * Function: Delist * Usage: element = Delist(list): *This function removes the student cell at the head of the list * and returns its address to the caller (client). If the list is empty, Delist * prints an Error with an appropriate message and returns NULL. student_cell_T *Delist(linked_list_T *list); * Functions: LinkedListIsEmpty, LinkedListIsFull * Usage: 19 (LinkedListIsEmpty(list) ... 11 (LinkedListIsFull(list)) ... * These functions test whether the list is empty or full. int LinkedListIsEmpty(linked_list_T *list); int LinkedListIsFull(linked_list_T *list); * Function: LinkedListLength * Usage: n = LinkedListLength(list); *This function returns the number of elements in the list. int LinkedListLength(linked_list_T *list); * Function: GetLinkedListElement * Usage: element = GetLinkedlistElement(list, index); * This function returns the element at the specified index in the * list, where the head of the list is defined as index 0. For * example, calling GetLinkedlistElement(list, B) returns the initial * element from the list without removing it. If the caller tries * to select an element that is out of range, GetLinkedListElement prints * Error and returns NULL. Note: This function is not a fundamental list operation * and is instead provided mainly to facilitate debugging. student_cell_T *GetLinkedListElement(linked_list_T slist, int Index); /* OTHER FUNCTIONS YOU WOULD NEED... * EXPORT THEM HERE, BUT IMPLMENT THEM in my linkedlist.c sendit #include #include #include "mylinkedlist.h" Function: ReadLine Usage: s = ReadLine(); ReadLine reads a line of text from standard input and returns * the line as a string. The newline ' ' character that terminates * the input is not stored as part of the string. */ char *ReadLine(void); int main(int argc, char *arvg[]) { // YOU NEED TO IMPLEMENT THIS driver1.c USING FUNCTIONS FROM mylinkedlist.h // But before that, implement your ReadLine() function, and test it as shown below. // IF NEEDED, YOU CAN ALSO IMLEMENT YOUR OWN FUNCTIONS HERE char *name; : "); printf("Enter a name to test your ReadLine function name = ReadLine(); printf("User entered : %s ", name); free (name); return 0; } * * IMPLEMENTATION of ReadLine(); * Function: ReadLine * Usage: s = ReadLine(); * ReadLine reads a line of text from standard input and returns the line as a string. The newline ' ' character that terminates the input is not stored as part of the string. In contrast to standard I/O functions (e.g., scanf with "5", fgets) that can read strings into a given static size buffer, ReadLine function * should read the given input line of characters terminated by a newline * character (' ') into a dynamically allocated and resized buffer based on the length of the given input line. * When implementing this function you can use standard I/O functions. We just want you to make sure you allocate enough space for the entered data. * So don't simply allocate 100 or 1000 bytes every time. * If the given input has 5 characters, you need to allocate space for 6 characters. * Hint: initially dynamically allocate an array of char with size 10. Then, read data into that array character by charecter (e.g, you can use getchar()). If you see ' ' char before reading 10th character, you are done. And you know the * exact length of the input string. So, accordingly allocate enough space and copy the data into new char array, insert '10' instead of ' ' and free the original array. * Then return the new string. However, if you DO NOT see ' ' char after 10th character, * then you need larger space. Accordingly, resize your original array and double its size * and continue reading data character by character as in the first step... Hope you got the idea! Also please check for possible errors (e.g., no memory etc.) and appropriately handle them. For example, if malloc returns NULL, free partially allocated space and return NULL from this function. The program calling this function may take other actions, e.g., stop the program! */ char *ReadLine() { // A SIMPLE WAY TO IMPLEMENT JUST TO TEST FOR NOW, BUT THIS IS NOT WHAT WE WANT!!! char *buff = malloc(100); scanf("%s", buff); return buff; // YOU NEED TO DELETE ABOVE 3 LINES, and IMPLEMENT THSI as described above return(NULL); // if there is any error! } #include #include #include "mylinkedlist.h" * Function: NewStudentCell * Usage: student_cell_t *element; element = NewStudentCell(int id, double gpa, char *name); This function allocates space for a student cell and intilize its fileds student_cell_t *NewStudentCell(int id, double gpa, char *name) student_cell_t *element; element = (student_cell_t *) malloc( sizeof(student_cell_T) ); if( !element) { fprintf(stderr, "NewStudentCell cannot allocate memory "); return NULL; element->id = id; element->gpa = gpa; element->name = name; return element; } /* Function: NewLinkedList Usage: linked_list_T *list; list = NewLinkedList(); This function allocates and returns an empty linked list. */ linked_list_T *NewLinkedList(void) { linked_list_T *list; list = (linked_list_T *) malloc( sizeof(linked_list_T) ); if( !list) { fprintf(stderr, "NewLinkedList cannot allocate memory "); return NULL; } list->head = NULL; list->tail = NULL; return list; } * * Function: FreeLinkedList Usage: FreeLinkedList(list); This function frees the storage associated with list. */ void FreeLinkedList(linked_list_T *list) { } * Function: Enlist Usage: Enlist(list, element); This function adds a student cell pointed by element to the end of the list. */ void Enlist(linked_list_t *list, student_cell_T *element) { } /* * Function: Delist Usage: element = Delist(list); * This function removes the student cell at the head of the list * and returns its address to the caller (client). If the list is empty, Delist * prints an Error with an appropriate message and returns NULL. student_cell_T *Delist(linked_list_T *list) { } * ** * Functions: LinkedListIsEmpty, LinkedListIsFull * Usage: if (LinkedListIsEmpty(list)) ... if (LinkedListIsFull(list)) ... * These functions test whether the list is empty or full. */ int LinkedListIsEmpty(linked_list_T *list) { } int LinkedListIsFull(linked_list_T *list) { return 0; // because we have linked list ** * Function: LinkedListLength * Usage: n = LinkedListLength(list); * This function returns the number of elements in the list. int LinkedListLength(linked_list_t *list) { } ** * Function: GetLinkedListElement * Usage: element = GetLinkedListElement(list, index); * This function returns the element at the specified index in the * list, where the head of the list is defined as index 0. For * example, calling GetLinkedListElement(list, 0) returns the initial * element from the list without removing it. If the caller tries * to select an element that is out of range, GetLinkedListElement prints * Error and returns NULL. Note: This function is not a fundamental list operation * and is instead provided mainly to facilitate debugging. */ student_cell_T *GetLinkedListElement(linked_list_T *list, int index) { } /* OTHER FUNCTIONS YOU WOULD NEED.... * EXPORT THEM HERE, BUT IMPLMENT THEM in mylinkedlist.c */ sifndef _mylinkedlist_h sdefine _mylinkedlist_h * Type: student cell * This type defines the cells used for the linked list that * stores the student information we use in assinge * You can change this structure later on for other assignments! typedef struct student_cell_T int 1d; double gpa; char .. *name: // name is just a pointer here, you need to allocate space for name struct student_cell_t *next; ) student_cellT * Type: linked list T * This type defines the concrete representation of a linked list of student cells. *The head field points to the first element in the linked list. * The tail field points to the last element in the linked list. * The empty linked list is indicated by a NULL head pointer. typedef struct linked_list_T{ student cell.T *head; student_cell_t *tail; } linked_list_T; * Function: NewStudentcell * Usage: student cell T element: * element = NewStudentcell(id, gpa, nane); This function allocates space for a student cell and intilize its fileds student_cell_T *NewStudentCell(int id, double gpa, char sname); * Function: NewLinkedlist Usage: linked_list_T *list; list - NewLinkedList: * This function allocates and returns an empty linked list. linked_list_T NewLinkedList(void); * Function: FreeLinkedList * Usage: FreeLinkedList(list); *This function frees the storage associated with list. void FreeLinkedList(linked_list_T slist); * Function: Enlist * Usage: Enlistilist, element); * This function adds a student cell pointed by element to the end of the list. * void Enlist (linked_list_t *list, student_cell_t *element); * Function: Delist * Usage: element = Delist(list): *This function removes the student cell at the head of the list * and returns its address to the caller (client). If the list is empty, Delist * prints an Error with an appropriate message and returns NULL. student_cell_T *Delist(linked_list_T *list); * Functions: LinkedListIsEmpty, LinkedListIsFull * Usage: 19 (LinkedListIsEmpty(list) ... 11 (LinkedListIsFull(list)) ... * These functions test whether the list is empty or full. int LinkedListIsEmpty(linked_list_T *list); int LinkedListIsFull(linked_list_T *list); * Function: LinkedListLength * Usage: n = LinkedListLength(list); *This function returns the number of elements in the list. int LinkedListLength(linked_list_T *list); * Function: GetLinkedListElement * Usage: element = GetLinkedlistElement(list, index); * This function returns the element at the specified index in the * list, where the head of the list is defined as index 0. For * example, calling GetLinkedlistElement(list, B) returns the initial * element from the list without removing it. If the caller tries * to select an element that is out of range, GetLinkedListElement prints * Error and returns NULL. Note: This function is not a fundamental list operation * and is instead provided mainly to facilitate debugging. student_cell_T *GetLinkedListElement(linked_list_T slist, int Index); /* OTHER FUNCTIONS YOU WOULD NEED... * EXPORT THEM HERE, BUT IMPLMENT THEM in my linkedlist.c sendit