I'm having a bit of trouble manipulating a program that I have already written, and could use some guidance.
The program I have written creates an array of structures that gets filled with data that is taken from a txt file. The program then displays the data onto the prompt in a formatted fashion.
Here is the code so far. (It runs with no errors.)
I now want to create a new function that opens the file, reads the file, and populates the elements of the array that can be filled by the input file. This function must be called at the beginning of the main function.
I have tried a few different solutions now, but have ended up with tons of errors on each.
I tried using cout to display a single array element to check if the results were good, but I could not find a place where the program recognized the array.
The only place where StudentRec_Array exists is inside the LoadDatabase function. The moment it reaches the end of the while loop the memory is being freed and the data is not available anymore.
Make it a global variable like you did with st_rec, this way it will be available everywhere.
And there's another thing. You want to pass a pointer to read_a_record, but you are passing a complete structure.
#define ARRAY_SIZE 100
typedefstruct{
string Name;
string ID;
double GPA;
}StudentRec;
ifstream st_rec;
StudentRec StudentRec_array[ARRAY_SIZE];
bool read_a_record (StudentRec *srec)
{
// read data from file until end of file
If(!st_rec.eof())
{
....
//srec is a pointer so acces member like this:
srec->Name = Name;
srec->ID =ID;
srec->GPA = GPA;
}
Return true;
}
void LoadDataBase()
{
//open file
//check open file here
//pass address of array element
while(read_a_record( &(StudentRec_array[i]) ))
i++;
// close file here
}
int main()
{
LoadDatabase();
// print name in first element.
cout << StudentRec_array[0].Name;
return 0;
}
Since that portion of code is now working, I have another question about the next portion of my code.
I am trying to create a menu for the user to choose from and the first option is to add another Student Record to the array, so I have come up with this code so far....
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
int main()
{
LoadDatabase();
int choice;
cout<<"\n\n Please choose one of the menu options:\n\n";
cout<<" (1) Add a Student Record\n";
cout<<" (2) Delete a Student Record\n";
cout<<" (3) Find a student's information\n";
cout<<" (4) Display entire database\n";
cout<<" (5) Exit the Program\n";
cin>>choice;
if(choice == 1)
{
Insert_Record();
}
void Insert_Record()
{
st_rec.open ("StudentRecord.txt");
if(st_rec.is_open())
{
string Name_insert;
string ID_insert;
string GPA_insert;
cout<<"\nWhat is the student's full name? ";
getline(cin,Name_insert);
cout<<"\nWhat is the student's ID? ";
getline(cin,ID_insert);
cout<<"\nWhat is the student's GPA?";
getline(cin,GPA_insert);
}
else
{
cout<<"file could not be opened.";
}
}
However, my getline()'s are causing me problems. When they are displayed on the prompt, the first one is skipped and then the display appears off by one. For instance, the prompt says "what is the student's full name? but gives the user no time to input the name, and jumps straight to "what is the student's ID?"
I have also not yet figured out how to add a value to the end of the array, I think I need to declare an int that tracks the end of the array then add the data input by the user onto the end of the array. Is this the right direction?
And you create new elements, why not use the already available element inside the array?
1 2 3 4 5 6 7 8 9 10 11 12 13 14
if(index < ARRAY_SIZE)
{
cout<<"\nWhat is the student's full name? ";
cin >> StudentRec_array[index].Name;
cout<<"\nWhat is the student's ID? ";
cin >> StudentRec_array[index].Name;
cout<<"\nWhat is the student's GPA?";
cin >> StudentRec_array[index].GPA;
//increase index
index++;
}
I guess you want to add the data to the file, but you are using ifstream. Which is a INPUT file stream.
#include <iostream>
#include <iomanip>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <string>
#include <sstream>
usingnamespace std;
ifstream st_rec;
int track_array=0;
struct StudentRec
{
string Name;
string ID;
double GPA;
};
constint ARRAY_SIZE =100;
StudentRec StudentRec_array[ARRAY_SIZE];
bool read_a_record (StudentRec& srec)
{
string fName,lName;
string vID;
double vGPA;
if(st_rec.is_open())
{
bool recordWasRead = st_rec>>fName>>lName>>vID>>vGPA;
if(! recordWasRead)
{
returnfalse;
}
srec.Name=lName+","+fName;
srec.ID=vID;
srec.GPA=vGPA;
returntrue;
}
else
{
cout<<"file could not be opened.";
returnfalse;
}
}
void LoadDatabase()
{
st_rec.open ("StudentRecord.txt");
int i=0;
if(st_rec.is_open())
{
while(read_a_record(StudentRec_array[i]))
{
i++;
track_array++;
}
}
else
cout<<"Unable to open file.";
st_rec.close();
}
void Insert_Record(StudentRec& srec)
{
st_rec.open ("StudentRecord.txt");
if(st_rec.is_open())
{
string Name_insert;
string ID_insert;
double GPA_insert;
cout<<"\nWhat is the student's full name? ";
getline(cin,Name_insert);
getline(cin,Name_insert);
cout<<"\nWhat is the student's ID? ";
getline(cin,ID_insert);
cout<<"\nWhat is the student's GPA? ";
cin>>GPA_insert;
if (track_array<ARRAY_SIZE)
{
srec.Name=Name_insert;
srec.ID=ID_insert;
srec.GPA=GPA_insert;
track_array++;
}
else
cout<<"Cannot accept entries larger than the array size.";
}
else
{
cout<<"file could not be opened.";
}
}
void Delete_Record()
{
}
void Find_Record()
{
int i;
string ID_Search;
cout<<"Please enter the ID of the student you wish to find information about.\n";
getline(cin,ID_Search);
getline(cin,ID_Search);
for(i=0;i<ARRAY_SIZE;i++)
{
if(StudentRec_array[i].ID==ID_Search)
{
cout<<"The student has been found.\n";
cout<<"Name: "<<StudentRec_array[i].Name<<"\n";
cout<<"ID: "<<StudentRec_array[i].ID<<"\n";
cout<<"GPA: "<<StudentRec_array[i].GPA<<"\n";
}
}
}
bool Print_Records(StudentRec srec)
{
cout<<srec.Name<<"\t\t";
cout<<srec.ID<<"\t\t";
cout<<srec.GPA<<endl;
}
int main()
{
LoadDatabase();
bool response;
int choice;
do
{
cout<<"\n\n Please choose one of the menu options:\n\n";
cout<<" (1) Add a Student Record\n";
cout<<" (2) Delete a Student Record\n";
cout<<" (3) Find a student's information\n";
cout<<" (4) Display entire database\n";
cout<<" (5) Exit the Program\n";
cin>>choice;
if(choice == 1)
{
int n=0;
Insert_Record(StudentRec_array[track_array]);
}
elseif(choice == 2)
{
Delete_Record();
}
elseif(choice == 3)
{
Find_Record();
}
elseif(choice == 4)
{
int rec_num=0;
int i=0;
st_rec.open ("StudentRecord.txt");
while(i<ARRAY_SIZE)
{
if(i<ARRAY_SIZE)
{
cout<<++rec_num<<"\t";
Print_Records(StudentRec_array[i]);
}
elsebreak;
i++;
}
}
elseif (choice == 5)
{
cout<<"Ending the Program\n";
}
else
{
cout<<"You must enter a valid choice between 1 and 5.\n";
cout<<"Please run the program again.\n\n";
}
cout<<"\n\nWould you like to choose another menu option?\n";
cout<<"Enter 0 for no. Enter 1 for yes.\n";
cin>>response;
}
while(response==1);
return 0;
}
When the user wants to find a students information, and the function Find_Record() is called, how can I display an error message for when no student ID match is found. I only want the message to display once, not for every i value that does not match.
I have also not yet figured out a way to implement the Delete_Record () function yet. Any tips would be much appreciated.
void Find_Record()
{
int i;
string ID_Search;
cout<<"Please enter the ID of the student you wish to find information about.\n";
getline(cin,ID_Search);
getline(cin,ID_Search);
for(i=0;i<track_array ;i++)
{
if(StudentRec_array[i].ID==ID_Search)
{
cout<<"The student has been found.\n";
cout<<"Name: "<<StudentRec_array[i].Name<<"\n";
cout<<"ID: "<<StudentRec_array[i].ID<<"\n";
cout<<"GPA: "<<StudentRec_array[i].GPA<<"\n";
//found it!
break;
}
}
if(i == track_array )
{
//reached the end of the data
cout << "Could not find student with id " << ID_Search << endl;
}
}
compare with track_array, not with ARRAY_SIZE. because the data in elements >= track_array is invalid data.
deleting a item is not that hard.
Just copy the other items over it.
start at the item you want to delete and just move everything.
1 2 3 4 5 6
for(int i = ID_Delete; i < (track_array - 1 ); i++)
{
StudentRec_array[i] = StudentRec_array[i+1];
}
//decrease index
track_array--;
ID_delete is the id of the element you want to delete, how you get this number is up to you.
(track_array-1) is the last valid value inside the array. all data from ID_Delete to (track_array-1) is being moved up 1 place. overwriting the one you want to delete.
Keep in mind that afterwards the elements StudentRec_array[track_array-1] and StudentRec_array[track_array] are the same. but because only the values < track_array are valid this is not a problem.
You are trying to write a array element to the file.
The element is of type StudentRec, but fstream does not know what he needs to do with a StudentRec element.
you need to write the data inside the element individially: