// READ BEFORE YOU START: // You are given a partially completed program that cr
ID: 3679974 • Letter: #
Question
// READ BEFORE YOU START: // You are given a partially completed program that creates a roster of students for a class. // Each student has the corresponding information: grade in the class and education level. // To begin, you should trace through the given code and understand how it works. // Please read the instructions above each required function and follow the directions carefully. // If you modify any of the given code, the return types, or the parameters, you risk failing the automated test cases. // // You are to assume that all input is valid: // Valid first name: String containing alphabetical letters beginning with a capital letter // Valid last name: String containing alphabetical letters beginning with a capital letter // Valid grade input: any integer value between 1 and 100 (error handling is implemented) // Valid education level input : f, so, j, or s. (error handling is implemented) // All input will be a valid length and no more than the allowed amount of memory will be input #include <stdio.h> #include <string.h> #include <ctype.h> // included to check for memory leaks (may need to comment out if you are using GCC) #define CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #pragma warning(disable : 4996) typedef enum { freshman = 0, sophomore, junior, senior } education; // enumeration type education level struct container { struct student *student; struct container *next; } *list = NULL; struct student { char firstName[100]; char lastName[100]; education level; int grade; }; // forward declarations void flush(); void branching(char c); void helper(char c); // average, search, and delete_one have already been implemented for you int add(struct student*); // 8 points double average(); // 4 points struct student* search(struct student*); // 4 points void delete_one(struct student*); // 8 points // These are new functions, 2 of them have already been implemented for you void print_helper(struct container*); struct container* print_all(struct container*); void delete_all(struct container*); // 4 points struct container* print_by_education_level(education); // 8 points void save(char*); // 4 points void load(char*); // 4 points // The remaining 6 points will be distributed for proper memory management // You must make sure that under no circumstances should you have memory leaks // If you are using Visual Studios, a function call has been provided in main for you // When your program exits, memory leaks will be displayed below in the output from Debug int main() { load("Student_List.txt"); // load list of students from file char ch = 'i'; printf("Student Roster: "); do { printf("Please enter your selection "); printf(" a: add a new student to the list "); printf(" d: delete a student from the list "); printf(" x: delete all students from the list "); printf(" s: search for student by name "); printf(" r: determine the class average "); printf(" p: print all students "); printf(" e: print students at an input education level "); printf(" q: quit and save list "); ch = tolower(getchar()); flush(); branching(ch); } while (ch != 'q'); save("Student_List.txt"); // save list of students to file delete_all(list); // delete list to prevent memory leaks _CrtDumpMemoryLeaks(); // check for memory leaks (may need to comment out if you are using GCC) return 0; } // consume leftover ' ' characters void flush() { int c; do c = getchar(); while (c != ' ' && c != EOF); } // branch to different tasks void branching(char c) { switch (c) { case 'a': case 'd': case 'x': case 's': case 'r': case 'p': case 'e': helper(c); break; case 'q': break; default: printf(" Invalid input! "); } } // The helper function is used to determine how much information is needed and which function to send that information to. // It uses pointers that are returned from some functions to produce the correct ouput. // There is no implementation needed here, but you should study this function and know how it works. // It is always helpful to understand how the code works before implementing new features. // Do not change anything in this function or you risk failing the automated test cases. void helper(char c) { char student_firstName[100]; char student_lastName[100]; education edu; int valid_level = -1; // used to determine if the input education level is acceptable int tempI; // temporary integer double tempD; // temporary double if (c == 'p') // print list of all students print_helper(print_all(list)); else if (c == 'e') // print by education level { char* student_level = (char*)malloc(100); // allocate memory printf(" Enter the education level (f/so/j/s): "); while (valid_level < 0) { scanf("%s", student_level); if (strcmp(student_level, "f") == 0){ valid_level++; edu = freshman; } else if (strcmp(student_level, "so") == 0){ valid_level++; edu = sophomore; } else if (strcmp(student_level, "j") == 0){ valid_level++; edu = junior; } else if (strcmp(student_level, "s") == 0){ valid_level++; edu = senior; } else printf("Please enter a valid education level (f/so/j/s). "); // error handling } struct container* p = print_by_education_level(edu); // store temporary list into pointer p print_helper(p); // print list flush(); // flush buffer // memory management while (p != NULL){ struct container* toDelete = p; p = p->next; free(toDelete->student); free(toDelete); toDelete = NULL; } free(student_level); // memory management } else if (c == 'x') // delete all students in list { delete_all(list); printf(" All students deleted. "); } else if (c == 'r') // compute class average { tempD = average(); if (tempD < 0) // tempD should equal -1 if the list is empty printf(" There are no students on the list. "); else printf(" The class average is: %.2f ", tempD); } else if (c == 'a') // add student { char* student_level = (char*)malloc(100); // create new temporary pointer struct student *ptr = (struct student *)malloc(sizeof(struct student)); printf(" Enter the student's first name: "); fgets(student_firstName, sizeof(student_firstName), stdin); printf(" Enter the student's last name: "); fgets(student_lastName, sizeof(student_lastName), stdin); // discard ' ' chars attached to input; NOTE: If you are using GCC, you may need to comment out these 2 lines student_firstName[strlen(student_firstName) - 1] = ''; student_lastName[strlen(student_lastName) - 1] = ''; // stores the first name and last name of the student into pointer strcpy(ptr->firstName, student_firstName); strcpy(ptr->lastName, student_lastName); printf(" Enter the student's grade: "); tempI = -1; while (tempI < 0 || tempI > 100) { scanf("%d", &tempI); if (tempI >= 0 && tempI <= 100) ptr->grade = tempI; // stores the grade of the student into pointer else printf("Please enter a grade between 0 and 100. "); } printf(" Enter the student's education level (f/so/j/s): "); // stores the education level of the student into pointer while (valid_level < 0) { scanf("%s", student_level); if (strcmp(student_level, "f") == 0){ valid_level++; ptr->level = freshman; } else if (strcmp(student_level, "so") == 0){ valid_level++; ptr->level = sophomore; } else if (strcmp(student_level, "j") == 0){ valid_level++; ptr->level = junior; } else if (strcmp(student_level, "s") == 0){ valid_level++; ptr->level = senior; } else printf("Please enter a valid education level (f/so/j/s). "); // error handling } tempI = add(ptr); // add student (should return 0 if the student is already on the list) if (tempI == 0) printf(" %s %s is already on the list. ", student_firstName, student_lastName); else printf(" %s %s added to the list. ", student_firstName, student_lastName); flush(); // flush buffer free(student_level); // memory management } else { // create new temporary pointer struct student *ptr = (struct student *)malloc(sizeof(struct student)); printf(" Enter the student's first name: "); fgets(student_firstName, sizeof(student_firstName), stdin); printf(" Enter the student's last name: "); fgets(student_lastName, sizeof(student_lastName), stdin); // discard ' ' chars attached to input; NOTE: If you are using GCC, you may need to comment out these lines student_firstName[strlen(student_firstName) - 1] = ''; student_lastName[strlen(student_lastName) - 1] = ''; // stores the first name of the student into pointer strcpy(ptr->firstName, student_firstName); // stores the last name of the student into pointer strcpy(ptr->lastName, student_lastName); struct student *temp = search(ptr); // search for student in list if (temp == NULL) // student not found printf(" %s %s not found. ", student_firstName, student_lastName); else if (c == 's') // student found printf(" Current grade for %s %s: %d ", student_firstName, temp->lastName, temp->grade); else // delete student { delete_one(ptr); printf(" %s %s deleted from the list. ", student_firstName, student_lastName); } free(ptr); // memory management } } // Q1: add (8) // Similar to hw06, you will be inserting into a list of students sorted by their last name. // Similar to hw05, there may be students on the list that have the same last name. // You will also be tested to assure that a student is not added to the list twice (same first name and last name). // If a student already exists with the same last name, then you will need to sort them by their first names. // // If the student is already on the list, return the integer value 0. // If the student is not on the list, add the student to the list and return the integer value 1. // // "list" is initialized as NULL. Use this as your 'head' of the list and insert into it accordingly. // There are 4 possibilities for inserting into the list: // - inserting into an empty list // - inserting at the beginning of the list // - inserting inbetween 2 nodes in the list // - inserting at the end of the list int add(struct student* new_student) { return 0; } // Q2: search (4) // In this function, you are passed a struct student* parameter named 'student' to find their current grade. // Stored inside this pointer, are the first and last names of the student that you want to find in your list (ex: student->lastName) // You need to return a pointer to a node in your list that contains that student's information (that will include student->grade) // To find that pointer, you need to traverse your lise. If that student does not exist in your list, you must return NULL. // (You must return a pointer to a node in your list. Do not create a pointer that just includes the grade, you will risk losing points) struct student* search(struct student* student) { return NULL; } // Q3: average (4) // In this function, you need to return the average of all of the students' grades that exist on the list. // To do this you will need to traverse your list and access each student's grade. // If there are no students on the list, you should return -1 (this will be tested). double average() { return 0.0; } // Q4: delete_one (8) // In this function, you are passed a struct student* parameter named 'student' to delete the corresponding student on your list. // Stored inside this pointer, are the first and last name of the student that you want to find in your list (ex: student->lastName) // The search function is called before this function to check if the student exists, you can assume that the student is on the list. // You will need to find the student and delete it using proper memory management to ensure no memory leaks. void delete_one(struct student* student) { } // print_helper prints student information from the parameter "studentsToPrint" in an organized format // If studentsToPrint is NULL, it prints, "Your list is empty!" // print_all and print_by_education_level (which is to be implemented) use this function to print a desired list of students void print_helper(struct container* studentsToPrint) { char* level = "freshman"; if (studentsToPrint == NULL) { printf(" This list is empty! "); return; } while (studentsToPrint != NULL) // traverse list of students { printf(" %s, %s ", studentsToPrint->student->lastName, studentsToPrint->student->firstName); if (studentsToPrint->student->level == freshman) level = "freshman"; else if (studentsToPrint->student->level == sophomore) level = "sophomore"; else if (studentsToPrint->student->level == junior) level = "junior"; else if (studentsToPrint->student->level == senior) level = "senior"; printf("Education level: %s ", level); printf("Grade: %d ", studentsToPrint->student->grade); studentsToPrint = studentsToPrint->next; } printf(" "); // formatting } // This function simply returns the list that is to be printed, it is already implemented for you struct container* print_all(struct container* students) { return students; } // Q5: delete_all (4) // Recursively delete the entire list of students. The parameter students is a pointer to your list. // You MUST use recursion, or you will recieve a 0 for this part. // (hint: don't forget to set your list back to NULL) void delete_all(struct container* students) { } // Q6: print_by_education_level (8) // Traverse your list and return a new list filled with students that are at the education level given by the enum parameter. // The students in the returned list should contain all of the information available for that student (firstName, lastName, grade, level) // The list of students that you return should be in alphabetical order (Your "list" should already be in alphabetical order) // If no students in your list are at the education level given by your parameter "edu", then return NULL struct container* print_by_education_level(education edu) { return NULL; } // Q7: save (4) // Save your linked list of containers to file. The filename is already implemented for you in main void save(char* fileName) { } // Q8: load (4) // Load your linked list of containers from file. The filename is already implemented for you in main void load(char* fileName) { }
Explanation / Answer
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define stacksize 4096
struct contact {
char name[30];
char phone[20];
char address[50];
int UserID;
struct contact *next;
}*head = NULL;
char *file_name;
int IDgenerator = 0;
int top = 0;
void menu();
void branching(char c);
struct contact* find_node(char *str, int *position);
void display_node(struct contact *node, int index);
void push(int val, int *stacktop, int *stack);
void pop(int *stacktop, int *stack);
int insert();
int deletion();
int modify();
int search_name();
void display_all();
void load_file();
void save_file();
void menu() {
int ch;
fflush(stdin);
printf(" MENU ");
printf("---- ");
printf("i: Insert a new entry. ");
printf("d: Delete an entry. ");
printf("m: Modify an entry. ");
printf("s: Search by name for an entry. ");
printf("p: Print all entries. ");
printf("q: Quit the program. ");
printf("Please enter your choice (i, d, m, s, p, or q) --> ");
scanf(%d,ch);
branching(ch);
}
void branching(char c) {
switch (c) {
case 'i': if (insert() != 0)
printf("INSERTION OPERATION FAILED. ");
else {
insert();
printf("INSERTED NODE IN THE LIST SUCCESSFULLY. ");
}
break;
case 'd': if (deletion() != 0)
printf("DELETION OPERATION FAILED. ");
else printf("DELETED THE ABOVE NODE SUCCESSFULLY. ");
break;
case 'm': if (modify() != 0)
printf("MODIFY OPERATION FAILED. ");
else printf("MODIFIED THE ABOVE NODE SUCCESSFULLY. ");
break;
case 's': if (search_name() != 0)
printf("SEARCH FAILED. ");
else printf("SEARCH FOR THE NODE SUCCESSFUL. ");
break;
case 'p': display_all();
break;
case 'q': save_file();
break;
default: printf("ERROR - Invalid input. ");
printf("Try again..... ");
break;
}
return;
}
int insert() {
struct contact *node;
char sname[30];
int index = 1;
printf(" Insertion module............... ");
printf("Enter the name of the person to be inserted: ");
scanf("%s", sname);
node = find_node(sname, &index);
if (node != NULL) {
printf("ERROR - Duplicate entry not allowed. ");
printf("A entry is found in the list at index %d. ", index);
display_node(node, index);
return -1;
}
else {
node = (struct contact*) malloc(sizeof(struct contact));
if (node == NULL) {
printf("ERROR - Could not allocate memory ! ");
return -1;
}
int push(node);
strcpy(node->name, sname);
printf("Enter telephone number: ");
scanf("%s", node->phone);
printf("Enter address: ");
scanf("%s", node->address);
node->next = head;
head = node; //link new node
return 0;
}
}
int deletion() {
char sname[30];
struct contact *temp, *prev;
int index = 1;
printf(" Deletion module............... ");
printf("Please enter the name of the person to be deleted: ");
scanf("%s", sname);
temp = head;
while (temp != NULL)
if (stricmp(sname, temp->name) != 0) {
prev = temp;
temp = temp->next;
index++;
}
else {
printf("Person to be deleted is found at index %d.", index);
display_node(temp, index);
if (temp != head)
prev->next = temp->next;
else
head = head->next;
free(temp);
return 0;
}
printf("The person with name '%s' does not exist. ", sname);
return -1;
}
int modify() {
struct contact *node;
char sname[30];
int index = 1;
printf(" Modification module............... ");
printf("Enter the name whose record is to be modified in the ");
printf("database: ");
scanf("%s", sname);
node = find_node(sname, &index);
if (node != NULL) {
printf("Person to be modified is found at index %d.", index);
display_node(node, index);
printf(" Enter the new telephone number of this person: ");
scanf("%s", node->phone);
printf("Enter the new address of this person: ");
scanf("%s", node->address);
return 0;
}
else {
printf("The person with name '%s' does not exist ", sname);
printf("database. ");
return -1;
}
}
int search_name() {
struct contact *node;
char sname[30];
int index = 1;
printf(" Search_name module............... ");
printf("Please enter the name to be searched in the database: ");
scanf("%s", sname);
node = find_node(sname, &index);
if (node != NULL) {
printf("Person searched is found at index %d.", index);
display_node(node, index);
return 0;
}
else {
printf("The person '%s' does not exist. ", sname);
return -1;
}
}
void display_all() {
struct contact *node;
int counter = 0;
printf(" Display module...............");
node = head;
while (node != NULL) {
display_node(node, counter++);
node = node->next;
}
printf(" No more records. ");
}
void load_file() {
FILE *file_descriptor;
struct contact *node, *temp;
char str[30];
file_descriptor = fopen(file_name, "r");
if (file_descriptor != NULL) {
while (fread(str, 30, 1, file_descriptor) == 1) {
node = (struct contact*) malloc(sizeof(struct contact));
strcpy(node->name, str);
fread(node->phone, 20, 1, file_descriptor);
fread(node->address, 50, 1, file_descriptor);
if (head != NULL)
temp->next = node;
else
head = node;
node->next = NULL;
temp = node;
}
fclose(file_descriptor);
}
}
void save_file() {
FILE *file_descriptor;
struct contact *node;
file_descriptor = fopen(file_name, "w");
if (file_descriptor != NULL) {
node = head;
while (node != NULL) {
fwrite(node->name, 30, 1, file_descriptor);
fwrite(node->phone, 20, 1, file_descriptor);
fwrite(node->address, 50, 1, file_descriptor);
node = node->next;
}
}
else {
printf(" ERROR - Could not open file for saving data ! ");
getchar();
exit(-1);
}
}struct contact* find_node(char *str, int *position) {
struct contact *temp = head;
while (temp != NULL) {
if (stricmp(str, temp->name) != 0) {
temp = temp->next;
(*position)++;
}
else
return temp;
}
return NULL;
}
void push(int *stack){
struct contact *temp;
temp = (struct contact*) malloc(sizeof(struct contact));
int IdStack = malloc(stacksize);
if (IdStack != 0)
int pop(int *stack);
else{
temp -> userID = IDgenerator;
IDgenerator=IDgenerator+1;
}
if (temp == NULL){
printf("stack is full");
}
}
void pop(int *stack)
{
struct contact *temp;
temp = malloc(sizeof(struct contact));
if((*stack) == NULL){
printf("The stack is empty. Pop is not allowed ");
return 0;
}
else{
temp = *stack;
stack = *temp;
}
free(temp);
return;
}
void display_node( struct contact *node, int index) {
printf(" RECORD %d: ", index);
printf(" Name: %s ", node->name);
printf(" Telephone: %s ", node->phone);
printf(" Address: %s ", node->address);
}
int main(int argc, char *argv[]) {
char ch;
if (argc != 2) {
printf("Command Line Parameters Required ! ");
printf("Try again...... ");
getchar();
return -1;
}
printf("SINGLY LINKED LIST ");
printf("******************");
file_name = argv[1];
load_file();
do {
menu();
fflush(stdin);
ch = tolower(getchar());
branching(ch);
} while (ch != 'q');
return 0;
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.