| 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();
}