Computer Science 2574 |
Intro to Data Structures & Soft Eng
|
#include "BuildList.h" #include "buildodb.h" struct TestInfo { int NumStudents; //These are the structures that the nodes for int NumQuestions; //the doubly linked lists will be built out of. int NumKeys; }; TestInfo ATest; struct MemoInfo //holds the current memo { char line1[Maxchars], line2[Maxchars]; }; MemoInfo Memo; struct KeyNode { KeyNode *Next; int QuestionNum; char Answer; }; struct KeyInfo { char SSNum[SSLength], FormCh, GroupNum; KeyNode *KeyListPtr; }; typedef KeyInfo* KeyInfoPtr; KeyInfoPtr Head[MaxKeys], K; KeyInfo AKey; struct StudentInfo { char Name[NameLength], SSN[SSLength], FormLetter, NumCorrect[5], GroupNum; int NumOmitted, SeatNum; float PercentCorrect, TScore; }; StudentInfo AStudent; struct AnswerNode { AnswerNode *Next; int QuestionNum; char Answer; }; AnswerNode AnAnswer; typedef AnswerNode* AnsNodePtr; AnsNodePtr l,p; struct StudentNode { AnsNodePtr AnswerListPtr; StudentNode *prev, *next; StudentInfo element; }; typedef StudentNode* StuNodePtr; StuNodePtr L, P, Header, Tail, HeadStudent, current; struct ODBNode { TestInfo ATest; KeyNode *AKeyPtrArray[MaxKeys]; StudentNode* list; }; void MoveCurrent(int DisplayNum); //************************************************************************** // Function: BuildList // Purpose: builds the linked lists for the student test and answer // information, by reading from an ODB file. // Called By: Main, View, BuildODB, OpenPrevious // Calls: clearscreen, odbmenu, DisplayAnswer, DisplayResults, // DisplayKeys, Resetmarker // // Parameters ifstream inFileODB - input file stream variable // int DisplayNum - number that determines how many records are // printed, depending on whether results or answers // are being displayed // // Return Value: void // Author: John W. Boyd III & Cullen J. Morris // Version 1.1 //************************************************************************** void BuildList(ifstream &inFileODB, int DisplayNum) { int j=0, NumberOfKeys = 0; char line[Maxchars]; inFileODB.getline(line, Maxchars); // read in lines of test info. and store them in strcat(Memo.line1, line); // in a struct inFileODB.getline(line, Maxchars); strcat(Memo.line2, line); //read in the line that holds the number of students, the number of test //questions, and the number of keys. Store them in the struct. inFileODB >> ATest.NumStudents >> ATest.NumQuestions; inFileODB >> ATest.NumKeys; NumberOfKeys = ATest.NumKeys; inFileODB.ignore(350,'\n'); //ignore the rest of the line while (NumberOfKeys != 0) { //read the keys and put their components in the appropriate nodes inFileODB >> AKey.SSNum >> AKey.FormCh >> AKey.GroupNum; K = new KeyInfo; //allocate a new node and fill in its fields strcpy(K->SSNum, AKey.SSNum); K->FormCh = AKey.FormCh; K->GroupNum = AKey.GroupNum; K->KeyListPtr = NULL; //set the pointer to the answer list to NULL K->KeyListPtr = new KeyNode; //allocate a new node for the answer list KeyNode *Key_temp = K->KeyListPtr; Head[j] = K; j++; for (int t = 1;t < ATest.NumQuestions; t++) //reads in each answer { Key_temp->QuestionNum = t; inFileODB >> Key_temp->Answer; Key_temp->Next = new KeyNode; Key_temp = Key_temp->Next; } Key_temp->QuestionNum = t; inFileODB >> Key_temp->Answer; Key_temp->Next = NULL; inFileODB.ignore(350,'\n'); NumberOfKeys--; } clearscreen(); StuNodePtr prevNode = NULL; P = NULL; L = NULL; StudentInfo element; inFileODB.get(AStudent.SSN, SSLength); inFileODB.get(AStudent.Name, NameLength-10); inFileODB.ignore(12,'\n'); inFileODB.get(AStudent.NumCorrect,5); inFileODB >> AStudent.NumOmitted; inFileODB >> AStudent.SeatNum >> AStudent.FormLetter; inFileODB >> AStudent.GroupNum >> AStudent.PercentCorrect; inFileODB >> AStudent.TScore; inFileODB.ignore(350, '\n'); P = new StudentNode; P->element = AStudent; P->next = NULL; P->prev = NULL; P->AnswerListPtr = new AnswerNode; AnswerNode *Answer_temp = P->AnswerListPtr; L = P; prevNode = L; HeadStudent = L; for (int t = 1;t < ATest.NumQuestions; t++) //reads in each answer { Answer_temp->QuestionNum = t; inFileODB >> Answer_temp->Answer; Answer_temp->Next = new AnswerNode; Answer_temp = Answer_temp->Next; } Answer_temp->QuestionNum = ATest.NumQuestions; inFileODB >> Answer_temp->Answer; Answer_temp->Next = NULL; inFileODB.ignore(350, '\n'); for (int i = 1; i < ATest.NumStudents; i++) //reads in student info for each student { inFileODB.get(AStudent.SSN,SSLength); inFileODB.get(AStudent.Name,NameLength-10); inFileODB.ignore(12,'\n'); inFileODB.get(AStudent.NumCorrect,5); inFileODB >> AStudent.NumOmitted; inFileODB >> AStudent.SeatNum >> AStudent.FormLetter; inFileODB >> AStudent.GroupNum >> AStudent.PercentCorrect; inFileODB >> AStudent.TScore; inFileODB.ignore(350, '\n'); P = new StudentNode; P->element = AStudent; P->next = NULL; P->prev = prevNode; prevNode->next = P; prevNode = P; P->AnswerListPtr = new AnswerNode; AnswerNode *Answer_temp = P->AnswerListPtr; for (int t = 1; t < ATest.NumQuestions; t++) //reads in student answers { Answer_temp->QuestionNum = t; inFileODB >> Answer_temp->Answer; Answer_temp->Next = new AnswerNode; Answer_temp = Answer_temp->Next; } Answer_temp->QuestionNum = t; inFileODB >> Answer_temp->Answer; Answer_temp->Next = NULL; inFileODB.ignore(350, '\n'); }//ends for Tail = prevNode; if (DisplayNum == ResultNum) //checks resultnum to see what should be displayed DisplayResults(); else { if (DisplayNum == 9) DisplayKeys(); else { if (DisplayNum == 0) odbmenu(); else DisplayAnswer(); } } ResetMarker(inFileODB); inFileODB.close(); } //************************************************************************** // Function: DisplayKeys // Purpose: displays all of the keys // Called By: BuildList, ViewMenu2 // Calls: AnswerHeader, odbmenu // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void DisplayKeys() { KeyNode *Key_temp = K->KeyListPtr; int i = 0, j = 0; AnswerHeader(); for (i = 0; i < ATest.NumKeys; i++) //outputs keys for viewing { j = 0; Key_temp = Head[i]->KeyListPtr; cout << " " << Head[i]->SSNum << " " << Head[i]->FormCh; cout << " " << Head[i]->GroupNum << " " ; cout << Key_temp->Answer; while ((Key_temp->Next != NULL) && (j < ATest.NumQuestions )) //outputs each key answer { Key_temp = Key_temp->Next; cout << Key_temp->Answer; j++; } cout << endl; } cout << endl; odbmenu(); } //************************************************************************** // Function: DisplayResults // Purpose: displays the first 20 students and their test information // Called By: BuildList, ViewMenu2 // Calls: clearscreen, viewmenu // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void DisplayResults() { cout.setf(ios::fixed, ios::floatfield); cout.setf(ios::showpoint); int count = 0, Less20 = 0; StudentNode *current = NULL; L = HeadStudent; current = HeadStudent; if (ATest.NumStudents < ResultNum) //count for when there are less than 20 students { count = ResultNum - ATest.NumStudents; Less20 = 1; } clearscreen(); cout << " SSN NAME Corr Omit Seat F G Grade TScr" << endl; cout << " ========================================================" << endl; while(count < ResultNum) //outputs Student info { cout << setw(3) << count + 1 << " " << L->element.SSN << " " << L->element.Name << " " << L->element.NumCorrect; cout << " " << L->element.NumOmitted << " " << L->element.SeatNum; cout << " " << L->element.FormLetter << " " << L->element.GroupNum; cout << " " << setw(2) << setprecision(0) << L->element.PercentCorrect; cout << " " << setw(2) << setprecision(0) << L->element.TScore; cout << endl; L = L->next; count++; } cout << endl; if (!Less20) //calls viewmenu viewmenu(ResultNum); } //************************************************************************** // Function: DisplayAnswer // Purpose: displays the first 15 students and their answers // Called By: BuildList, ViewMenu2 // Calls: AnswerHeader, ViewMenu2 // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void DisplayAnswer() { AnswerHeader(); int j = 0, i = 0; L = HeadStudent; current = L; AnswerNode *Answer_temp = L->AnswerListPtr; while ( j < AnswerNum ) // outputs answers for each student { i=0; if(L->element.Name[1]=='?') //puts SSN in name field if they didn't fill in their name cout << setw(3) << j + 1 << " " << setw(11) << L->element.SSN; else cout << setw(3) << j + 1 << " " << setw(11) << L->element.Name; cout << " " << L->element.FormLetter << " " << L->element.GroupNum; cout << " "; while ((Answer_temp != NULL) && (i++ < ATest.NumQuestions )) //outputs answers { cout << Answer_temp->Answer; Answer_temp = Answer_temp->Next; } cout << endl; if(L->next != NULL) // moves thru the list until next = NULL { L = L->next; Answer_temp = L->AnswerListPtr; } j++; } cout << endl; viewmenu(AnswerNum); } //************************************************************************** // Function: Escape // Purpose: To quit the program // Called By: FileMenu, View // Calls: clearscreen, Terminationscreen // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void Escape() { int exitStatus = 0; clearscreen(); TerminationScreen(); exit(exitStatus); } //****************************************************************************** // Function: viewmenu // Purpose: To display the view menu and read in the choice // Called By: Top, Up, Bottom, Stop, Down, Samescreen, EditMenu // Calls: Top, Up, Bottom, Stop, Down, Samescreen, EditMenu // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //****************************************************************************** #include "menus.h" #include "displayoptns.h" void viewmenu(int DisplayNum) { char viewch; cout << "\t(T)op, (U)p, (D)own, (B)ottom, (E)dit, or (S)top?"<>viewch; while(viewch != 'T' && viewch != 'D' && viewch != 'B' && viewch != 'S' && viewch != 'U' && viewch != 'E') //makes sure they input the right character { cout << endl << "\tInvalid response, please re-enter." << endl; cin >> viewch; } clearscreen(); switch (viewch) //depending on which option they chose it calls a display function { case 'T': Top(DisplayNum); break; case 'U': Up(DisplayNum); break; case 'D': Down(DisplayNum); break; case 'B': Bottom(DisplayNum); break; case 'S': Stop(DisplayNum); break; case 'E': SameScreen(DisplayNum); EditMenu(DisplayNum); break; } } //************************************************************************** // Function: Top // Purpose: To display the top group of records // Called By: viewmenu // Calls: AnswerHeader, viewmenu // Parameters: DisplayNum - Number of students to display for Results and // Answers // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void Top(int DisplayNum) { current = L; int count = 0, i = 0; for (int j = 0; j < (DisplayNum) && L->prev != NULL; j++) //moves the pointer backwards L = L->prev; if(DisplayNum == 20) //checks to see what to display Answers or Results { if (L->prev == NULL) //tells them if they are at the top of the list { cout << "\tInvalid operation, already at top of list." << endl << endl; viewmenu(DisplayNum); } L = HeadStudent; AnswerNode *Answer_temp = L->AnswerListPtr; while (L->prev != NULL) // moves the pointer to the first node L = L->prev; cout << " SSN NAME Corr Omit Seat F G Grade TScr" << endl; cout << " ========================================================" << endl; while(count < DisplayNum) //outputs the results 20 at a time { cout << setw(3) << count + 1 << " " << L->element.SSN << " " << L->element.Name << " " << L->element.NumCorrect; cout << " " << L->element.NumOmitted << " " << L->element.SeatNum; cout << " " << L->element.FormLetter << " " << L->element.GroupNum; cout << " " << setw(2) << setprecision(0) << L->element.PercentCorrect; cout << " " << setw(2) << setprecision(0) << L->element.TScore; cout << endl; L = L->next; count++; } } //end if else //outputs the answers { count = 0; if (L->prev == NULL) //checks to see if previous pointer is null { cout << "\tInvalid operation, already at top of list." << endl << endl; viewmenu(DisplayNum); } L = HeadStudent; current = L; AnswerNode *Answer_temp = L->AnswerListPtr; AnswerHeader(); while (count < DisplayNum) //outputs the answers at a time { i = 0; if(L->element.Name[1]=='?') //puts SSN in name field if they didn't fill in their name cout << setw(3) << count + 1 << " " << setw(11) << L->element.SSN; else cout << setw(3) << count + 1 << " " << setw(11) << L->element.Name; cout << " " << L->element.FormLetter << " "; cout << L->element.GroupNum << " "; while ((Answer_temp != NULL) && (i++ < ATest.NumQuestions )) //checks for NULL pointer { cout << Answer_temp->Answer; Answer_temp = Answer_temp->Next; } cout << endl; count++; L = L->next; Answer_temp = L->AnswerListPtr; } }//end else cout << endl; viewmenu(DisplayNum); } //************************************************************************** // Function: Down // Purpose: To move down the list to the next group // of records. // Called By: viewmenu // Calls: AnswerHeader, viewmenu // Parameters: DisplayNum - Number of students to display for Results and // Answers // Return Value: int zero // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** int Down(int DisplayNum) { AnswerNode *Answer_temp = L->AnswerListPtr; current = L; int i = 0, j = 0, count = 0; if (DisplayNum == 20) //checks to see what to display, answers or results. { if (L->next == NULL) //checks to see if L->next equal NULL { cout << endl << "\tInvalid Operation, already at bottom of list." << endl << endl; viewmenu(DisplayNum); return 0; } cout << " SSN NAME Corr Omit Seat F G Grade TScr" << endl; cout << " ========================================================" << endl; while ((i < DisplayNum) && (L->next != NULL)) //makes sure L->next isn't NULL { L = L->next; i++; } int t = 0; if(L->next == NULL) { DisplayNum--; t=1; } while (j < DisplayNum) //moves pointer up { L = L->prev; j++; } if(t == 1) DisplayNum++; while (count < DisplayNum) //outputs student info 20 at a time { cout << setw(3) << count + 1 << " " << L->element.SSN << " " << L->element.Name << " " << L->element.NumCorrect; cout << " " << L->element.NumOmitted << " " << L->element.SeatNum; cout << " " << L->element.FormLetter << " " << L->element.GroupNum; cout << " " << setw(2) << setprecision(0) << L->element.PercentCorrect; cout << " " << setw(2) << setprecision(0) << L->element.TScore; cout << endl; L->next; count++; if (L->next != NULL) // makes sure L-> !=Null L = L->next; } } //end if else //outputs students and their answers { count = 0; i = 0; j = 0; if (L->next == NULL) //tells the user they are at the bottom of the list { cout << endl << "\tInvalid Operation, already at bottom of list." << endl << endl; viewmenu(DisplayNum); return 0; } AnswerHeader(); while ((i < DisplayNum) && (L->next != NULL)) //moves the pointer ahead { L = L->next; i++; } while (j < DisplayNum) //moves the pointer back { L = L->prev; j++; } Answer_temp = L->AnswerListPtr; while (count < DisplayNum) //outputs the students and their answers { i = 0; if(L->element.Name[1]=='?') //puts SSN in name field if they didn't fill in their name cout << setw(3) << count + 1 << " " << setw(11) << L->element.SSN; else cout << setw(3) << count + 1 << " " << setw(11) << L->element.Name; cout << " " << L->element.FormLetter << " " << L->element.GroupNum; cout << " "; while ((Answer_temp != NULL) && (i++ < ATest.NumQuestions )) //outputs the students answers { cout << Answer_temp->Answer; Answer_temp = Answer_temp->Next; } cout << endl; count++; if(L->next != NULL) //moves pointer down list until next = NULL { L = L->next; Answer_temp = L->AnswerListPtr; } } }// end else cout << endl; viewmenu(DisplayNum); return 0; } //************************************************************************** // Function: Bottom // Purpose: To move to the bottom of the list to of // records. // Called By: viewmenu // Calls: AnswerHeader, viewmenu // Parameters: DisplayNum - Number of students to display for Results and // Answers // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void Bottom(int DisplayNum) { int i = 0, count = 0; AnswerNode *Answer_temp = L->AnswerListPtr; if (DisplayNum == 20) //checks to see what to display, answers or student info { if (L->next == NULL) //tells the user if they are at the bottom of the list { cout << "\tInvalid response, already at bottom of list." << endl << endl; viewmenu(DisplayNum); } L = Tail; for(i=1; i < DisplayNum; i++) //moves L back L = L->prev; current = L; cout << " SSN NAME Corr Omit Seat F G Grade TScr" << endl; cout << " ========================================================" << endl; while(count < DisplayNum) //outputs the student info { cout << setw(3) << count + 1 << " " << L->element.SSN << " " << L->element.Name << " " << L->element.NumCorrect; cout << " " << L->element.NumOmitted << " " << L->element.SeatNum; cout << " " << L->element.FormLetter << " " << L->element.GroupNum; cout << " " << setw(2) << setprecision(0) << L->element.PercentCorrect; cout << " " << setw(2) << setprecision(0) << L->element.TScore; cout << endl; count++; L->next; if (L->next != NULL) // advances the pointer L = L->next; } } else //displays the answers { count = 0; if (L->next == NULL) //tells the user they are at the bottom of the list { cout << endl <<"\tInvalid response, already at bottom of list." << endl << endl; viewmenu(DisplayNum); } AnswerHeader(); L = Tail; for(i=1; i < DisplayNum; i++) //moves L up the list { L = L->prev; } current = L; while (count < DisplayNum) //outputs the students and their answers { Answer_temp = L->AnswerListPtr; i = 0; if(L->element.Name[1]=='?') //puts SSN in name field if they didn't fill in their name cout << setw(3) << count + 1 << " " << setw(11) << L->element.SSN; else cout << setw(3) << count + 1 << " " << setw(11) << L->element.Name; cout << " " << L->element.FormLetter << " " << L->element.GroupNum; cout << " "; while ((Answer_temp != NULL) && (i++ < ATest.NumQuestions )) //outputs the student answers { cout << Answer_temp->Answer; Answer_temp = Answer_temp->Next; } cout << endl; count++; if(L->next != NULL)// advances pointer one node L = L->next; } }//end else cout << endl; viewmenu(DisplayNum); } //************************************************************************** // Function: Up // Purpose: This function shows the previous group of records. // Called By: viewmenu // Calls: AnswerHeader, viewmenu // Parameters: DisplayNum - Number of students to display for Results and // Answers // Return Value: int zero // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** int Up(int DisplayNum) { AnswerNode *Answer_temp = L->AnswerListPtr; int i = 0, j = 0, count = 0; for (j = 0; j < (DisplayNum) && L->prev != NULL; j++) //moves the pointer backwards L = L->prev; if (L->prev == NULL) //tells the user they are at the top of the list { cout << endl << "\tInvalid Operation, already at top of list." << endl << endl; viewmenu(DisplayNum); return 0; } for (j = 0; j < (DisplayNum) && L->prev != NULL; j++) //moves the pointer backwards L = L->prev; current = L; if (DisplayNum == 20) //checks to see what to display, answers or results. { cout << " SSN NAME Corr Omit Seat F G Grade TScr" << endl; cout << " ========================================================" << endl; while(count < DisplayNum) //outputs the list { cout << setw(3) << count + 1 << " " << L->element.SSN << " " << L->element.Name << " " << L->element.NumCorrect; cout << " " << L->element.NumOmitted << " " << L->element.SeatNum; cout << " " << L->element.FormLetter << " " << L->element.GroupNum; cout << " " << setw(2) << setprecision(0) << L->element.PercentCorrect; cout << " " << setw(2) << setprecision(0) << L->element.TScore; cout << endl; count++; L->next; if (L->next != NULL) // advances L down the list L = L->next; } } else //outputs the students answers { count = 0; AnswerHeader(); current = L; while(count < DisplayNum) // outputs the students and their answers { i = 0; if(L->element.Name[1]=='?') //puts SSN in name field if they didn't fill in their name cout << setw(3) << count + 1 << " " << setw(11) << L->element.SSN; else cout << setw(3) << count + 1 << " " << setw(11) << L->element.Name; cout << " " << L->element.FormLetter << " "; cout << L->element.GroupNum << " "; Answer_temp = L->AnswerListPtr; while ((Answer_temp != NULL) && (i++ < ATest.NumQuestions )) //outputs the students answers { cout << Answer_temp->Answer; Answer_temp = Answer_temp->Next; } cout << endl; count++; if(L->next != NULL) // moves pointer down list one node L = L->next; } }//end else cout << endl; viewmenu(DisplayNum); return 0; } //************************************************************************** // Function: SameScreen // Purpose: redisplays the current screen of list elements // Called By: viewmenu, EditMenu, MoveCurrent // Calls: AnswerHeader, viewmenu // Parameters: DisplayNum - Number of students to display for Results and // Answers // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void SameScreen(int DisplayNum) { int count = 0; AnswerNode *Answer_temp = L->AnswerListPtr; for (int j = 0; j < (DisplayNum) && L->prev != NULL; j++) //moves the pointer backwards L = L->prev; if (DisplayNum == 20) //checks to see what to display, answers or results. { cout << " SSN NAME Corr Omit Seat F G Grade TScr" << endl; cout << " ========================================================" << endl; current = L; while(count < DisplayNum) //outputs the list { cout << setw(3) << count + 1 << " " << L->element.SSN << " " << L->element.Name << " " << L->element.NumCorrect; cout << " " << L->element.NumOmitted << " " << L->element.SeatNum; cout << " " << L->element.FormLetter << " " << L->element.GroupNum; cout << " " << setw(2) << setprecision(0) << L->element.PercentCorrect; cout << " " << setw(2) << setprecision(0) << L->element.TScore; cout << endl; count++; L->next; if (L->next != NULL) // advances L down the list L = L->next; } } else //outputs the students answers { count = 0; AnswerHeader(); current = L; while(count < DisplayNum) // outputs the students and their answers { int i = 0; if(L->element.Name[1]=='?') //puts SSN in name field if they didn't fill in their name cout << setw(3) << count + 1 << " " << setw(11) << L->element.SSN; else cout << setw(3) << count + 1 << " " << setw(11) << L->element.Name; cout << " " << L->element.FormLetter << " " << L->element.GroupNum; cout << " "; Answer_temp = L->AnswerListPtr; while ((Answer_temp != NULL) && (i++ < ATest.NumQuestions )) //outputs the students answers { cout << Answer_temp->Answer; Answer_temp = Answer_temp->Next; } cout << endl; count++; if(L->next != NULL) // moves pointer down list one L = L->next; } }//end else cout << endl; for (j = 0; j < (DisplayNum) && L->prev != NULL; j++) //moves the pointer backwards L = L->prev; } //************************************************************************** // Function: Stop // Purpose: This function stops the list viewing and returns the user // to the ODB menu // Called By: viewmenu // Calls: clearscreen, odbmenu // Parameters: DisplayNum - Number of students to display for Results and // Answers // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void Stop(int DisplayNum) { clearscreen(); odbmenu(); cout << endl; } //******************************************************************************** // Function: AnswerHeader // Purpose: Display the answer header // Called By: DisplayKeys, DisplayAnswers, Top, Down, Bottom, Up, SameScreen // Calls: NONE // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //******************************************************************************** void AnswerHeader() { clearscreen(); cout << " G A N S W E R S " << endl; cout << " F R" << endl; cout << " STUDENT O O question numbers " << endl; cout << " NAME R U 00000000011111111112222222222333333333344444444445" << endl; cout << " M P 12345678901234567890123456789012345678901234567890" << endl; cout << " ==================================================================" << endl; } //************************************************************************** // Function: EditSSN // Purpose: Allows the user to edit a student social security number // Called By: EditMenu // Calls: clearscreen, odbmenu // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void EditSSN() { char NewSSN[SSLength], tmpchar; int t = 0, resultNum = 20; MoveCurrent(resultNum); cout << " Please enter the new SSN or press enter to escape edit SSN." << endl; cin.getline(NewSSN, SSLength); cin.getline(NewSSN, SSLength); if (!NewSSN[0]) // checks to see if the string is empty t = SSLength - 1; else { while(isdigit(NewSSN[t])) t++; } if (t != SSLength - 1) // checks to make sure the SSN is of valid lenght { clearscreen(); cout << "Invalid SSN." << endl; EditSSN(); } if (!NewSSN[0]) // checks to see if change has been made cout << " No change has been made. Press enter to return to the main menu." << endl; else { strcpy(current->element.SSN, NewSSN); cout << "Your change has been made. Press enter to continue." << endl; } scanf("%c",&tmpchar); //read in a character from the keyboard while(tmpchar != '\n') //make sure the character is the newline { scanf("%c",&tmpchar); } clearscreen(); odbmenu(); } //************************************************************************** // Function: EditName // Purpose: Allows the user to edit a student's name // Called By: EditMenu // Calls: MoveCurrent, odbmenu, clearscreen // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void EditName() { char NewName[NameLength], tempName[NameLength], BlankString[NameLength] = " ", tmpchar; int resultNum = 20, k = 0, t = 0; MoveCurrent(resultNum); cout << "Please enter the new student last name."; cout << endl; cin.getline(tempName,NameLength); cin.getline(NewName, NameLength); if (!NewName[0])// checks to see if change has been made cout << " No change has been made. Press enter to return to the main menu." << endl; else { strcat(BlankString, NewName); k = strlen(BlankString); t = ShortName - k; while (t != 1) // alligns colums for tabular format by adding 2 blanks to name { strcat(BlankString, Blank); t--; } strcpy(current->element.Name, BlankString); cout << "Your change has been made. Press enter to continue." << endl; } scanf("%c",&tmpchar); //read in a character from the keyboard while(tmpchar != '\n') //make sure the character is the newline { scanf("%c",&tmpchar); } clearscreen(); odbmenu(); } //************************************************************************** // Function: EditForm // Purpose: Allows the user to edit a student's form letter // Called By: EditMenu // Calls: MoveCurrent, clearscreen, odbmenu // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void EditForm() { char NewForm, tmpchar; int resultNum = 20; MoveCurrent(resultNum); cout << "Please enter the new form letter."; cout << endl; scanf("%c", &NewForm); if (NewForm == '\n') // checks to see if changes have been made to the form cout << "No change has been made. Press enter to return to the main menu." << endl; else { while (!isalpha(NewForm))// checks to make sure input is valid { clearscreen(); cout << endl << "Invalid Form Letter. Please re-enter." << endl; cin >> NewForm; } toupper(NewForm); current->element.FormLetter = NewForm; cout << "Your change has been made. Press enter to continue." << endl; } scanf("%c",&tmpchar); scanf("%c",&tmpchar); //read in a character from the keyboard while(tmpchar != '\n') //make sure the character is the newline { scanf("%c",&tmpchar); } clearscreen(); odbmenu(); } //************************************************************************** // Function: EditGroup // Purpose: Allows the user to edit a student's group number // Called By: EditMenu // Calls: MoveCurrent, odbmenu, clearscreen // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void EditGroup() { char NewGroup, tmpchar; int resultNum = 20; MoveCurrent(resultNum); cout << "Please enter the new group number."; cout << endl; scanf("%c", &NewGroup); if (NewGroup == '\n') // checks to see if group has been edited cout << "No change has been made. Press enter to return to the main menu." << endl; else { while(!isdigit(NewGroup)) // makes sure input is vaild { clearscreen(); cout << "Invalid response. Please re-enter group number." << endl; cin >> NewGroup; } current->element.GroupNum = NewGroup; cout << "Your change has been made. Press enter to continue." << endl; } scanf("%c",&tmpchar); scanf("%c",&tmpchar); //read in a character from the keyboard while(tmpchar != '\n') //make sure the character is the newline { scanf("%c",&tmpchar); } clearscreen(); odbmenu(); } //************************************************************************** // Function: EditChair // Purpose: Allows the user to edit a student's chair number // Called By: EditMenu // Calls: MoveCurrent, odbmenu, clearscreen // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** #include void EditChair() { char NewChair[2]; int ChairNum = 0, resultNum = 20; char tmpchar; MoveCurrent(resultNum); cout << "Please enter the new chair number."; cout << endl; scanf("%c", &NewChair); if (NewChair[0] == '\n') // checks to see if chair has been edited cout << "No change has been made. Press enter to return to the main menu." << endl; else { ChairNum = atoi(NewChair); current->element.SeatNum = ChairNum; cout << " Your change has been made. Press enter to continue." << endl; } scanf("%c",&tmpchar); scanf("%c",&tmpchar); //read in a character from the keyboard while(tmpchar != '\n') //make sure the character is the newline { scanf("%c",&tmpchar); } clearscreen(); odbmenu(); } //************************************************************************** // Function: EditAnswer // Purpose: Allows the user to edit a student's answer to a question // Called By: EditMenu // Calls: Movecurrent, clearscreen, odbmenu // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void EditAnswer() { char NewAnswer[2], tmpchar; int QuestionNum, i = 0, answerNum = 15; MoveCurrent(answerNum); cout << "Please enter the question number you would like to edit."; cout << endl; cin >> QuestionNum; AnswerNode *Answer_temp = current->AnswerListPtr; while ( i < QuestionNum - 1)// moves pointer to correct position for editing { Answer_temp = Answer_temp->Next; i++; } cout << endl << "Please enter the new student answer." << endl; scanf("%c", &NewAnswer); if (NewAnswer[0] == '\n') // checks to see if answer has been edited cout << "No change has been made. Press enter to return to the main menu." << endl; else { while (!isdigit(NewAnswer[0])) // checks to see if input is vaild { clearscreen(); cout << endl << "Invalid response. Please re-enter the new answer." << endl; cin >> NewAnswer; } Answer_temp->Answer = NewAnswer[0]; cout << endl << "Your change has been made." << endl; } scanf("%c",&tmpchar); scanf("%c",&tmpchar); //read in a character from the keyboard while(tmpchar != '\n') //make sure the character is the newline { scanf("%c",&tmpchar); } clearscreen(); odbmenu(); } //************************************************************************** // Function: ChangeKey // Purpose: To let the user change the answers in the keys // Called By: KeyMenu // Calls: odbmenu, clearscreen // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void ChangeKey() { char NewAnswer[2], tmpchar; int QuestionNum, i = 0, j = 0; char formletter; KeyNode *Key_temp = K->KeyListPtr; cout << "Please enter the form letter of the key you wish to edit."; cout << endl; cin >> formletter; while (formletter != Head[i]->FormCh) // moves to the correct key i++; cout << "Please enter the question number that you wish to change."; cout << endl; cin >> QuestionNum; KeyNode *TmpPtr; TmpPtr = Head[i]->KeyListPtr; while (j < QuestionNum - 1)// moves pointer to correct answer { TmpPtr = TmpPtr->Next; j++; } cout << endl << "Please enter the new key answer." << endl; scanf("%c", NewAnswer); if (NewAnswer[0] == '\n') // checks to see if anser has been edited cout << "No change has been made. Press enter to return to the main menu." << endl; else { while (!isdigit(NewAnswer[0]) || NewAnswer[1] != '\0') // checks to make sure input { // is valid clearscreen(); cout << endl << "Invalid response. Please re-enter the new answer." << endl; cin >> NewAnswer; } TmpPtr->Answer = NewAnswer[0]; cout << endl << "Your change has been made. Press enter to continue." << endl; } scanf("%c",&tmpchar); //read in a character from the keyboard while(tmpchar != '\n') //make sure the character is the newline { scanf("%c",&tmpchar); } clearscreen(); odbmenu(); } //************************************************************************** // Function: EditMemo // Purpose: Allows the user to edit the odb file memo // Called By: EditMenu // Calls: odbmenu, clearscreen // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void EditMemo() { char tmpchar, templine1[Maxchars]; clearscreen(); cout << "This is your current memo:" << endl << endl << endl; cout << Memo.line1 << endl << Memo.line2 << endl << endl; cin.getline(templine1,Maxchars); cout << endl << endl << "\t Please enter Line 1 of your new memo." << endl; cin.getline(templine1, Maxchars); if (!templine1[0]) // checks to see if memo has been chaged cout << "No changes have been made. Press enter to return to the main menu." << endl; else { strcpy(Memo.line1, templine1); cout << endl << "\t Please enter Line 2 of your new memo." << endl; cin.getline(Memo.line2, Maxchars); cout << endl << endl << "\t Your change has been made. Press enter to continue." << endl; } scanf("%c",&tmpchar); //read in a character from the keyboard while(tmpchar != '\n') //make sure the character is the newline { scanf("%c",&tmpchar); } clearscreen(); odbmenu(); } //************************************************************************** // Function: Statistics // Purpose: recalculates the standard deviation and the average // of the grades // Called By: ViewMenu2, CalculateMenu // Calls: odbmenu, clearscreen // Parameters: int showstat - value to determine if the statistics // are displayed // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** #include void Statistics(int showstat) { float x = 0.0, xtotal = 0.0, xSqrd = 0.0, xSqrdTotal = 0.0, StdDev = 0.0, Avg = 0.0; int i = 0; char tmpchar; cout.setf(ios::fixed, ios::floatfield); cout.setf(ios::showpoint); L = HeadStudent; for (i; i < ATest.NumStudents; i++) // reads in and adds up each students test score { x = L->element.PercentCorrect; xtotal = x + xtotal; xSqrd = x*x; xSqrdTotal = xSqrd + xSqrdTotal; L = L->next; } StdDev = sqrt((xSqrdTotal - ((xtotal)*(xtotal) /ATest.NumStudents))/ATest.NumStudents); Avg = xtotal/ATest.NumStudents; clearscreen(); cout << endl << " The standard deviation and average have been calculated." << endl << endl; if (showstat) // checks to see if stats should be displayed { cout << Memo.line1 << endl; cout << Memo.line2 << endl << endl; cout << endl << " The class average is: " << setw(5); cout << setprecision(2) << Avg << endl; cout << endl << " The standard deviation for the class is: "; cout << setw(5) << setprecision(2) << StdDev << endl; } cout << endl << endl << " Press enter to continue." << endl; scanf("%c",&tmpchar); //read in a character from the keyboard while(tmpchar != '\n') //make sure the character is the newline { scanf("%c",&tmpchar); } clearscreen(); cout << endl; odbmenu(); } //************************************************************************** // Function: ReGrade // Purpose: regrade the test with the edited answers or keys // Called By: CalculateMenu // Calls: odbmenu, // Parameters: NONE // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void ReGrade() { int i = 0, right, wrong, omit; float Grade = 0.0; char correct[5]; AnswerNode *Answer_temp = L->AnswerListPtr; KeyNode *Key_temp = Head[i]->KeyListPtr; L = HeadStudent; while (L->next != NULL) // goes thru each student { i = 0; right = 0; wrong = 0; omit = 0; while (L->element.FormLetter != Head[i]->FormCh) // gets to correct key for grading i++; Answer_temp = L->AnswerListPtr; Key_temp = Head[i]->KeyListPtr; while (Answer_temp != NULL && Key_temp != NULL) // makes sure that pointer is // not at end each list { if (Answer_temp->Answer == Key_temp->Answer) // checks to see if answer is correct right++; else wrong++; if (Answer_temp->Answer == '?') // checks to see if the omitted the question omit++; Key_temp = Key_temp->Next; Answer_temp = Answer_temp->Next; } Grade = (float(right)/ATest.NumQuestions) * 100.0; itoa(right,correct,10); L->element.PercentCorrect = Grade; strcpy(L->element.NumCorrect, correct); L->element.NumOmitted = omit; L = L->next; } odbmenu(); } //***************************************************************************** // Function: destroylist // Purpose: destroys all of the nodes of the linked list structure // Called By: Close // Calls: NONE // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //****************************************************************************** void destroyList() { L = HeadStudent; AnswerNode *Answer_temp = L->AnswerListPtr; StuNodePtr del = L; AnswerNode *DEL = Answer_temp; while (L->next != NULL) // goes thru each student to delete list { AnswerNode *Answer_temp = L->AnswerListPtr; while (Answer_temp->Next != NULL) // goes thru answers { Answer_temp = Answer_temp->Next; delete DEL; DEL = Answer_temp; } L = L->next; delete del; del = L; } } //*********************************************************************************** // Function: Close // Purpose: This function closes the open ODB file // Called By: FileMenu // Calls: clearscreen, odbmenu, destroylist, // Parameters: inFileODB - closes the ODB file opened for building the list // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //*********************************************************************************** void Close(ifstream &FileODB) { if (!L || L->next == NULL)// checks to see if file is not open or already closed { clearscreen(); cout << " Invalid operation. Must have an open file to close." << endl; odbmenu(); } else { destroyList(); FileODB.close(); clearscreen(); odbmenu(); } } //************************************************************************** // Function: MoveCurrent // Purpose: Moves the current pointer to the position that the // user wishes to edit // Called By: EditName, EditForm, EditChair, EditAnswer, EditGroup // Calls: SameScreem // Parameters: int DisplayNum - Value that determines which type of student // record that is displayed // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void MoveCurrent(int DisplayNum) { int lineNum; SameScreen(DisplayNum); cout << " Please enter the line number of the line you wish to edit." << endl; cin >> lineNum; for (int i = 1; i < lineNum; i++) //moves current pointer to the user selected line current = current->next; } //************************************************************************** // Function: Save // Purpose: Save the current list structure // Called By: FileMenu, SaveAs // Calls: odbmenu // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void Save() { int j = 0, i = 0, NumberOfKeys = 0; char ODBname[NameLength] = ""; AnswerNode *Answer_temp = L->AnswerListPtr; KeyNode *Key_temp = Head[i]->KeyListPtr; ofstream outFile; ifstream inFile; inFile.open(tempfile); inFile >> ODBname; outFile.open(ODBname); outFile << Memo.line1 << endl; outFile << Memo.line2 << endl; outFile << ATest.NumStudents << " " << ATest.NumQuestions << " " << ATest.NumKeys << endl; NumberOfKeys = ATest.NumKeys; for (i; i < ATest.NumKeys; i++) // goes thru keys to output each to file { outFile << Head[i]->SSNum << " " << Head[i]->FormCh << " " << Head[i]->GroupNum << " "; Key_temp = Head[i]->KeyListPtr; j = 0; while (j < ATest.NumQuestions) // writes key answers to file { outFile << Key_temp->Answer; Key_temp = Key_temp->Next; j++; } outFile << endl; } L = HeadStudent; while (L != NULL) // writes student info to file { outFile << L->element.SSN << " " << L->element.Name << " " << L->element.NumCorrect; outFile << " " << L->element.NumOmitted << " " << L->element.SeatNum; outFile << " " << L->element.FormLetter << " " << L->element.GroupNum; outFile << " " << L->element.PercentCorrect << " " << L->element.TScore; outFile << endl; i = 0; Answer_temp = L->AnswerListPtr; while ((Answer_temp != NULL) && (i++ < ATest.NumQuestions )) //outputs answers { outFile << Answer_temp->Answer; Answer_temp = Answer_temp->Next; } outFile << endl; L = L->next; } odbmenu(); } //************************************************************************** // Function: SaveAs // Purpose: Saves the current list to disk with new filename // Called By: FileMenu // Calls: Save, GetODBName // Parameters: NONE // Return Value: void // Authors: John W. Boyd III & Cullen J. Morris // Version: 1.1 //************************************************************************** void SaveAs() { ofstream outFile; ofstream data; char ODBFileName[NameLength], ODBExt[ExtensionLength] = ".odb"; getODBname(ODBFileName, ODBExt, outFile); // gets name of file to be saved outFile.close(); data.open(tempfile); data << ODBFileName; data.close(); Save(); }