Hello everyone
I have been trying to learn the greater mysteries of linked lists and have come across an error that is inexplicable to me at my current level of understanding.
I have written a program that attempts to form a linked list to store student information in the form of a struct. This code is a modified version of an earlier program that I wrote that implemented the same functionality using arrays. The program reads the data from a file StudentRecords.txt, then allows the user to search it, display all the data, or add or delete a student record, as well as writing any changes made back into the file
The primary issue is with the DisplayDatabase and LoadDatabase functions, which work as intended the first time the user displays the database, but prints all of the information in the file again after the first set when it is called a second time.
Thus, if the user selects (4) from the menu once, then again selects (4), the information will be printed twice the second time.
Here is the code. I am sorry that it is so long, but I felt that I should post all of it, since I am not sure what exactly is causing the problem.
#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
#include <iomanip>
#include <stdio.h>
using namespace std;
int check = 0; // Input validation statement..
int limit = 99;
struct StudentRec // Structure to define variables in the Student Records.
{
string Name; // String data for the Name of studnet.
string ID; // String name for the ID # of the student.
double GPA; // Define GPA of students.
bool compare(StudentRec valid) // Validate data
{
if(Name == valid.Name && ID == valid.ID && GPA == valid.GPA) // If statment to validate data
return true; // If correct, return true
return false; // If incorrect, return false.
}
};
struct StudentListNode
{
StudentRec StudentData;
StudentListNode *next;
};
StudentListNode*startpoint=NULL;
void LoadDatabase() //load the txt to array
{
bool check = false;
StudentListNode *temp, *temp2, *temp3;
StudentRec student;
string full, nmlst, nmfst,id, nm; //variables needed for reading in
double gpa; //
ifstream file;
ofstream create; //
file.open("StudentRecords.txt"); //read the file
if (!file)
{ //error output
cerr << "Can't open input file " << endl;
create.open("StudentRecords.txt");
create.close();
}
while(file >> nmfst >> nmlst >> id >> gpa) //for to read the correct loop
{
check = false;
temp = new StudentListNode;
nm = nmlst + ", " +nmfst;
student.Name = nm;
student.ID = id;
student.GPA = gpa;
temp -> StudentData = student;
temp -> next = NULL;
if(startpoint == NULL)
{
startpoint = temp;
}
else
{
temp2 = startpoint;
// We know this is not NULL - list not empty!
while (temp2->next != NULL)
{
temp3=temp2->next;
if(((temp2->StudentData.Name) < (temp->StudentData.Name)) && ((temp3->StudentData.Name) > (temp->StudentData.Name)))
{
temp2->next = temp;
temp->next = temp3;
check = true;
break;
}
else
{
temp2 = temp2->next;
}
// Move to next link in chain
}
if(temp2->next == NULL && !check)
{
temp2->next = temp;
}
}
}
file.close();
}
void print_a_record(StudentRec show)
{
// Display data in orderly and readable fashion. Left center data.
cout
<< left << setw(32) << show.Name
<< setw(10) << show.ID
<< setw(7) << fixed << setprecision(2) << show.GPA << endl;
}
void Displaydatabase()
{
StudentListNode*temp;
int x=0;
temp = startpoint;
cout << endl;
if (temp == NULL)
{
cout << " No Student Record" << endl;
}
else
{
cout << right << "No. " << setw(15) << "Name: " << setw(31) << "ID: " << setw(10) << "GPA\n"
<< "------------------------------------------------------------------ \n";
while (temp != NULL)
{
if (x<9)
{
cout << x+1 << ". " << setw(10) << " ";
}
else if (x<100)
{
cout << x+1 << ". " << setw(9) << " ";
}
else
{
cout << x+1 << ". " << setw(8) << " ";
}
print_a_record(temp-> StudentData);
temp = temp->next;
x++;
}
}
}
// Function to be called so a , is not implimented in the text file when its not needed.
string convertName(string name)
{
string nmlst, nlst;
int count =0;
for (int x = 0; x < name.size(); x++)
{
if (count ==0)
{
if (name[x] != ' ' && name[x] != ', ')
{
nlst +=name[x];
}
else count ++;
}
else
{
if(name[x] != ', ')
nmlst += name[x];
}
}
name = nmlst + " " + nlst;
return name;
}
// Function to call menu and display information to user.
// Function to add a record to the file.
void addsrecord ()
//Function apple >>> 0002
{
StudentListNode *temp, *temp2, *temp3;
temp = new StudentListNode;
string last,first,name,id;double gpa;
string gpatest; //to test gpa making sure it is int
StudentRec student; //temporary student
cout << "What is the last name?\n";
cin >> last;
cout << "What is the first name?\n";
cin >>first;
name = last +", " +first; // add name last, first format
cout << "What is the ID?\n";
cin >> id; // get the gpa
cout << "What is the gpa?\n";
cin >> gpa;
student.Name = name; //set everything
student.ID = id;
student.GPA = gpa;
temp->StudentData = student;
temp->next = NULL;
temp2 = startpoint;
if(startpoint == NULL)
{
startpoint = temp;
}
else
{
while (temp2->next != NULL)
{
temp3=temp2->next;
if(((temp2->StudentData.Name) <= (temp->StudentData.Name)) && ((temp3->StudentData.Name) > (temp->StudentData.Name)))
{
temp2->next = temp;
temp->next = temp3;
break;
}
else
{
temp2 = temp2->next;
}
// Move to next link in chain
}
if(temp2->next == NULL)
{
temp2->next = temp;
}
}
}
// Function that allows user to deltee a student record by entering their M #.
void delsrecord ()
{
// Variables.
//Student chosen >>>>>>> 0005
string id;
StudentListNode *temp, *temp2;
temp = startpoint;
if(startpoint == NULL)
cout << "There are no students" << endl;
else
{
cout << "What is the ID?? " << endl;
cin >> id;
if(id == temp->StudentData.ID)
{
cout << "Record was delteed" << endl;
startpoint = startpoint->next;
delete temp;
}
else
{
temp = startpoint; temp2 = temp->next;
if(temp->next == NULL)
{
cout << "Student can't be found!!" << endl;
}
else
{
while ((temp2->next !=NULL) && (temp2->StudentData.ID != id))
{
temp = temp->next;
temp2= temp->next;
}
if(temp2->StudentData.ID == id)
{
temp->next = temp2->next;
cout << "Record has been deleted" << endl;
delete temp2;
}
}
}
}
}
// Function to find a record within the file. Using a bianary search.
void findsrecord()
{
string input;
cout << "Enter the ID number of the student you wish to find (M########) " << endl;
cin >> input;
// Loop to compare strings for the search.
while (startpoint!=NULL)
{
if(startpoint->StudentData.ID == input)
{
cout << "Student has been found." << endl;
cout << "Name: " << startpoint->StudentData.Name << endl << "GPA: " << startpoint->StudentData.GPA << endl <<
"ID: " << startpoint->StudentData.ID << endl;
return;
}
// cout << count << limit << endl;
// If the number is not found in the file.
if (startpoint == NULL)
{
cout << "Can't find student!" << endl;
}
else
{
startpoint = startpoint->next;
continue;
}
}
}
// Function that saves the information passed through the array to the .txt file.
void save()
{
ofstream file;
file.open("StudentRecords.txt");
string temper; // A convertName for students[p].Name
// Command to pass all data to file from array.
while((startpoint != NULL))
{
temper = convertName(startpoint->StudentData.Name);
file << temper<< " " << startpoint->StudentData.ID << " " << startpoint->StudentData.GPA << endl;
startpoint = startpoint -> next;
}
file.close();
}
void pickChoice() //Gives user choices in program.
{
cout << "********************************************************************************" << endl;
cout << "\t\t\t(1) Add a student record." << endl;
cout << "\t\t\t(2) Delete a student record." << endl;
cout << "\t\t\t(3) Find a student's information." << endl;
cout << "\t\t\t(4) Display all information in the database." << endl;
cout << "\t\t\t(5) Exit program." << endl;
cout << "********************************************************************************" << endl;
}
// Void statement to display menu to user.
void displayMenu()
{
bool temp = true;
//LoadDatabase();
while(temp != false)
{
pickChoice();
int choice;
cin >> choice;
while(!cin.good() || choice < 1 || choice > 5)
{
cin.clear();
cin.ignore( 80, '\n' );
cout << endl << "Invalid entry. Enter an integer 1 - 5: " << endl;
pickChoice();
cin >> choice;
}
switch(choice)
{
case 1: LoadDatabase();
addsrecord();
save();
break;
case 2: LoadDatabase();
delsrecord();
save();
break;
case 3: LoadDatabase();
findsrecord();
break;
case 4: LoadDatabase();
Displaydatabase();
break;
case 5: LoadDatabase();
exit(1);
break;
default:cout << "Enter a valid choice please." << endl;
break;
}
}
}
int main()
{
displayMenu(); //Display menu
return 0;
}
If anyone has any insights on what could be causing this error, they would be greatly appreciated.
Thanks
ace8957