Ok, here is the complete code, my problem is with the ListFileHDD function. The requirement of this assignment was that I do not change the function prototypes or any of the main() code, but I simply write the functions.
Code:
#include <iostream>
#include <fstream>
using namespace std;
struct StudentRecord
{
char* firstName; // student key
char* lastName; // student name
int id; // student id
float mark; // course mark
};
bool LoadFileToMemory(ifstream& fin, StudentRecord**& Records, int& numRecords);
void ListFileHDD(ifstream& fin);
bool AddRecord(StudentRecord**& Records, int& numRecords);
void ListFileMem(StudentRecord** Records, int numRecords);
bool SaveToFile(StudentRecord** Records,int numRecords, char* fileName);
void SortLastNameAscending(StudentRecord**,int);
void SortLastNameDescending(StudentRecord**,int);
void CleanUp(StudentRecord**& Records, int numRecords);
int main(){
// all the student records as an array of pointers to StudentRecords
StudentRecord** Records;
int numRecords = 0; // how many
char FileName[20]; // file to open
// Get the file name to open
cout<<"Please enter the name of the file containing student records: ";
cin>>FileName;
ifstream fin(FileName,ios::in); // use a constructor to make the stream;
if(!fin)
{
cerr<<"Opening file for 1st time"<<endl;
ofstream fout(FileName,ios::out); // open for 1st time
fout.close(); // then promptly close
}
// Copy the file into memory
if(!LoadFileToMemory(fin,Records,numRecords))
{
cout<<"Failed to load file into memory";
return 1;
}
char response;
do
{
// The menu
cout<<"1. List the file from HDD"<<endl;
cout<<"2. List the file from dynamic memory"<<endl;
cout<<"3. Add a new record in dynamic memory"<<endl;
cout<<"4. Sort records (in dynamic memory) in lastname ascending order"<<endl;
cout<<"5. Sort records (in dynamic memory) in lastname descending order"<<endl;
cout<<"6. Save dynamic memory to file"<<endl;
cout<<"7. Quit"<<endl;
cin>>response;
switch(response)
{
case '1':
ListFileHDD(fin);
break;
case '2':
ListFileMem(Records,numRecords);
break;
case '3':
if(!AddRecord(Records,numRecords))
{
cout<<"Failed to Add Record";
return 1;
}
break;
case '4':
SortLastNameAscending(Records,numRecords);
break;
case '5':
SortLastNameDescending(Records,numRecords);
break;
case '6':
if(!SaveToFile(Records,numRecords,FileName))
{
cout<<"Failed to Add Record";
return 1;
}
break;
case '7':
// close file stream
fin.close();
// release memory
CleanUp(Records,numRecords);
return 0;
}
}while(true);
return 0;
}
/****************************************************************************************
Function Name : LoadFileToMemory
Purpose : function will read in from a file, and store the records in a
dynamically allocated StudentRecord **
Function Inputs : ifstream& fin - the location of the already opened file
StudentRecord**& Records - the array of records
numRecords - number of elements in the array
Function Outputs: boolean value - true if all records were loaded successfully,
false if something failed
*****************************************************************************************/
bool LoadFileToMemory(ifstream& fin, StudentRecord**& Records, int& numRecords)
{
cout <<"LOAD FILE INTO MEMORY\n";
char firstName[255];
char lastName[255];
int size = 1; //an initial size for the StudentRecord array
struct StudentRecord ** tempRecords;
while(!fin.eof())
{
if((size -1) == numRecords)
{
tempRecords = new StudentRecord*[size];
for(int i = 0; i < numRecords; i++)
tempRecords[i] = Records[i];
size++;
Records = new StudentRecord*[size];
for (i = 0; i < numRecords; i++)
Records[i] = tempRecords[i];
}
if(!(fin >> firstName >> lastName))
{
if(numRecords == 0)
{
cout <<"There are 0 student records in file\n";
return true;
}
break;
}
Records[numRecords] = new struct StudentRecord;
Records[numRecords]->firstName = new char[strlen(firstName) + 1];
Records[numRecords]->lastName = new char[strlen(lastName) + 1];
strcpy(Records[numRecords]->firstName,firstName);
strcpy(Records[numRecords]->lastName,lastName);
if(!(fin >> Records[numRecords]->id >> Records[numRecords]->mark))
break;
numRecords += 1;
}
fin.close();
//delete the temporary array of pointers
delete [] tempRecords;
cout <<"There are " << numRecords << "student records.\n";
return true;
}
/****************************************************************************************
Function Name : ListFileHDD
Purpose : function will display the contents of the StudentRecord array, as it
appears from the file
Function Inputs : ifstream& fin - the location of the already opened file
Function Outputs: None
*****************************************************************************************/
void ListFileHDD(ifstream& fin)
{
cout<<"LIST FILES FROM HDD\n";
char firstName[255], lastName[255];
int id;
float mark;
fin.clear();
fin.seekg(0,ios::beg);
cout <<"File pointer is at " << fin.tellg() << endl;
while(!fin.eof())
{
if(!(fin >> firstName >> lastName >> id >> mark))
break;
cout
<<"First Name: " << firstName <<"\tLast Name: " << lastName
<<"\tStudent ID: " << id <<"\tStudent Mark: " << mark << endl;
}
return;
}
/****************************************************************************************
Function Name : AddRecord
Purpose : function will add a record to the StudentRecord array located in memory
Function Inputs : StudentRecord**& Records - the array of records
int& numRecords - number of elements in the array
Function Outputs: boolean value - true if a record was successfully added
false if there was an error
*****************************************************************************************/
bool AddRecord(StudentRecord**& Records, int& numRecords)
{
char firstName[255],lastName[255];
StudentRecord ** tempRecords;
//resize records array to store one more student record
tempRecords = new StudentRecord*[numRecords];
for(int i = 0; i < numRecords; i++)
tempRecords[i] = Records[i];
numRecords++;
Records = new StudentRecord*[numRecords];
for (i = 0; i < numRecords; i++)
Records[i] = tempRecords[i];
//get rid of the temporary array of pointers
delete [] tempRecords;
Records[numRecords-1] = new struct StudentRecord;
//now get the information and add it to the record
cout <<"\nFirst Name:";
cin >> firstName;
cout <<"\nLast Name:";
cin >> lastName;
cout <<"\nId:";
cin >> Records[numRecords-1]->id;
cout <<"\nMark:";
cin >> Records[numRecords-1]->mark;
Records[numRecords-1]->firstName = new char[strlen(firstName) + 1];
Records[numRecords-1]->lastName = new char[strlen(lastName) + 1];
strcpy(Records[numRecords-1]->firstName,firstName);
strcpy(Records[numRecords-1]->lastName,lastName);
return true;
}
/****************************************************************************************
Function Name : ListFileMem
Purpose : function will display the contents of the StudentRecord array, as it
appears in memory
Function Inputs : StudentRecord** Records - the array of student records
int numRecords - the number of elements in the array
Function Outputs: None
*****************************************************************************************/
void ListFileMem(StudentRecord** Records, int numRecords)
{
cout <<"LIST RECORDS FROM MEMORY\n";
for(int i = 0; i < numRecords; i++)
cout<<"\nRecord " << i <<":"
<<"\tName: " << Records[i]->firstName <<" " << Records[i]->lastName
<<"\n\tStudent ID: " << Records[i]->id <<"\tStudent Mark: " << Records[i]->mark << endl;
return;
}
/****************************************************************************************
Function Name : SaveToFile
Purpose : Saves the contents of the StudentRecord** to the file specified at run-time
Function Inputs : StudentRecord** Records - the array of student records
int numRecords - the number of elements in the array
char* fileName - the file to open for write
Function Outputs: boolean value - true if file was successfully written to
false if any errors occured
*****************************************************************************************/
bool SaveToFile(StudentRecord** Records,int numRecords, char* fileName)
{
//If there are no records, do not write
if(numRecords == 0)
{
cerr <<"No records exist\n";
return true;
}
//open file and write each entry to file, closing promptly afterwards
ofstream fout(fileName,ios::out);
for(int i = 0; i < numRecords; i++)
{
if(!(fout << Records[i]->firstName << " " << Records[i]->lastName << " " << Records[i]->id << " " << Records[i]->mark))
return false;
if(i != numRecords)
fout << endl;
}
fout.close();
return true;
}
/****************************************************************************************
Function Name : SortLastNameAscending
Purpose : function will bubblesort the array based on the last names of records
Function Inputs : StudentRecord** -
int - the number of records
Function Outputs: None
*****************************************************************************************/
void SortLastNameAscending(StudentRecord** Records,int numRecords)
{
if(Records == NULL)
return;
cout<<"SORT NAMES ASCENDING\n";
StudentRecord * temp;
for(int i = 0; i < numRecords - 1; i++)
{
for(int j = 0; j < numRecords - 1; j++)
{
if((strcmp(Records[j]->lastName,Records[j+1]->lastName)) > 0)
{
temp = Records[j];
Records[j] = Records[j+1];
Records[j+1] = temp;
}
}
}
return;
}
/****************************************************************************************
Function Name : SortLastNameDescending
Purpose : function will bubblesort the array based on the last names of records
Function Inputs : StudentRecord** -
int - the number of records
Function Outputs: None
*****************************************************************************************/
void SortLastNameDescending(StudentRecord** Records,int numRecords)
{
if(Records == NULL)
return;
cout<<"SORT NAMES DESCENDING\n";
StudentRecord * temp;
for(int i = 0; i < numRecords - 1; i++)
for(int j = 0; j < numRecords - 1; j++)
{
if((strcmp(Records[j]->lastName,Records[j+1]->lastName)) < 0)
{
temp = Records[j];
Records[j] = Records[j+1];
Records[j+1] = temp;
}
}
return;
}
/****************************************************************************************
Function Name : CleanUp
Purpose : function will clean up and release all dynamically allocated memory from
the StudentRecord array before terminating
Function Inputs : StudentRecord** Records - the array of student records
int numRecords - the number of elements in the array
Function Outputs: None
*****************************************************************************************/
void CleanUp(StudentRecord**& Records, int numRecords)
{
if(Records == NULL)
return;
for(int i = 0; i < numRecords; i++)
{
delete [] (Records[i]->firstName);
delete [] (Records[i]->lastName);
delete Records[i];
}
delete [] Records;
return;
}