Passing a struct array and updating array in C++ - c++

For one of my options, I had to add a row of data to my struct array, I was able to update the array but it does not update the actual array. So I am trying to update my struct array by passing it as a reference. I placed the '&' sign before the name of the variable, but all my indexes within the function errored.. I'm still a newbie to programing and I'm not "allowed " to use any vectors according to my Professor. . I looked online and placed the '&' on the function name as well as on the prototype. I also changed it from void to the "data type" to return the updated array, but no luck... I hope this comes out clear....
#include<iostream>
#include<iomanip>
#include<fstream>
using namespace std;
struct Data {
string first_name;
string last_name;
int employee_id;
string phone_number;
};
void readFile( ifstream& , string, Data [],int&);
void getEmployeeDetail(Data [], int&);
void getEmployeeLast(Data [], int&);
Data getAddEmployee(Data &, int&);
void getRemoveEmployee();
void getManagerOnly();
void getStaffOnly();
const int SIZE = 15;
Data employee[SIZE];
int main() {
ifstream inputFile;
ofstream outputFile;
int count = 0;
int selection;
const int EMPLOYEE_DETAIL = 1,
EMPLOYEE_LAST = 2,
ADD_EMPLOYEE = 3,
REMOVE_EMPLOYEE = 4,
MANAGER_ONLY = 5,
STAFF_ONLY = 6,
QUIT = 7;
readFile( inputFile ,"employeeData.txt", employee,count);
do {
cout << "\t Please select your option.\n"
<< "1. List all employee details\n"
<< "2. List employee by last name\n"
<< "3. Add a new employee\n"
<< "4. Remove an employee\n"
<< "5. Show all managers only\n"
<< "6. Show all staff only\n"
<< "7. Quit\n"
<< "Please enter your selection.\n" << endl;
cin >> selection;
while (selection < EMPLOYEE_DETAIL || selection > QUIT) {
cout << " Pleasse enter a valid selection.\n";
cin >> selection;
}
switch (selection) {
case EMPLOYEE_DETAIL:
getEmployeeDetail(employee,count);
break;
case EMPLOYEE_LAST:
getEmployeeLast(employee, count);
break;
case ADD_EMPLOYEE:
getAddEmployee(employee, count);
break;
case REMOVE_EMPLOYEE:
getRemoveEmployee();
break;
case MANAGER_ONLY:
getManagerOnly();
break;
case STAFF_ONLY:
getStaffOnly();
break;
case QUIT:
cout << "Program ending\n";
break;
}
} while (selection != QUIT);
system("pause");
return(0);
}
void readFile(ifstream& inputFile, string data, Data employee[],int &count) {
inputFile.open(data);
if (!inputFile) {
cout << " Error in opening file\n";
exit(1);
}
else {
while (!inputFile.eof()) {
inputFile >> employee[count].first_name;
inputFile >> employee[count].last_name >> employee[count].employee_id >> employee[count].phone_number;
count++;
}
inputFile.close();
}
return;
};
void readFile(ifstream& inputFile, string data, Data employee[],int &count) {
inputFile.open(data);
if (!inputFile) {
cout << " Error in opening file\n";
exit(1);
}
else {
while (!inputFile.eof()) {
inputFile >> employee[count].first_name;
inputFile >> employee[count].last_name >> employee[count].employee_id >> employee[count].phone_number;
count++;
}
inputFile.close();
}
return;
};
void getEmployeeDetail( Data employee[], int& count) {
cout << "Firt Name" << "\t" << "Last Name " << "\t" << "Employee ID " << "\t" << "Phone Number \n";
cout << "--------------------------------------------------------------------------\n";
for(int i =0; i < count; i++)
cout <<employee[i].first_name<<"\t\t"<<employee[i].last_name<<"\t\t"<<employee[i].employee_id<<"\t\t"<<employee[i].phone_number<< "\n ";
cout << endl;
}
void getEmployeeLast(Data employee[], int& count) {
string searchName;
cout << "Please enter the last name of the employee you want to search for.\n";
cin >> searchName;
/*
for (int i = 0; i < count; i++)
if (searchName ==employee[i].last_name) {
cout << employee[i].last_name;
}
*/
string matchString = searchName;
for (int i = 0; i < count; i++) {
if (employee[i].last_name.find(matchString, 0) != std::string::npos) {
cout << employee[i].last_name << endl;
}
else {
cout << "No employee was located with that name.\n";
exit(1);
}
}
}
Data getAddEmployee(Data &employee, int& count) {
string firstName, lastName, phoneNumber;
int employeeID, size;
for (int i = 0; i < count; i++)
cout << employee[i].first_name << "\t\t\t" << employee[i].last_name << "\t\t" << employee[i].employee_id << "\t\t" << employee[i].phone_number << "\n ";
cout << endl;
cout << count <<"\n";
size = count + 1;
cout << size << "\n";
cout << "Please enter the new employee First Name.\n";
cin >> firstName;
cout << "Please enter the new employee Last Name.\n";
cin >> lastName;
cout << "Please enter the new employee's ID.\n";
cin >> employeeID;
cout << "Please enter the new employee Phone Number.\n";
cin >> phoneNumber;
employee[10].first_name = firstName;
employee[10].last_name = lastName;
employee[10].employee_id = employeeID;
employee[10].phone_number = phoneNumber;
for (int i = 0; i < size; i++) {
cout << employee[i].first_name << "\t\t\t" << employee[i].last_name << "\t\t" << employee[i].employee_id << "\t\t" << employee[i].phone_number << "\n ";
cout << endl;
}
return employee;
}

First of all, your naming could be better. Like employeeList instead employee to specify its a list/array of employee, also addEmployee instead of getAddEmployee.
Second, instead of pasting whole code, it's better to paste the relevant block of code based on your question to make it clearer.
The solution is, your array is basically already on global scope, you don't need to pass it. Can just directly modify the array.
struct Data {
string first_name;
string last_name;
int employee_id;
string phone_number;
};
void addEmployee();
const int SIZE = 15;
Data employeeList[SIZE];
int current = 0;
int main(){
Data emp1 = {"John", "Doe", 100, "12345"};
employeeList[0] = emp1;
current++;
addEmployee();
for(int i=0; i<current; i++){
Data emp = employeeList[i];
cout<<i+1<<" "<<emp.first_name<<" "<<emp.phone_number<<endl;
}
}
void addEmployee(){
Data emp2 = {"Sam", "Smith", 200, "67890"};
employeeList[current] = emp2;
current++;
}
Can try it here: https://onlinegdb.com/drhzEOpis

Related

String Type Vector C++

In the code I shared below, I want to output vector data type in the AddStoreCustomer() section. This is how the code works. But there is a bug in the code. If I enter a single word in the customer variable, the code works fine. But when I enter two words in this variable with a space between them,the code doesn't work.
#include <iostream>
#include <vector>
using namespace std;
class Store {
int StoreID;
string StoreName;
string StoreCity;
string StoreTown;
string StoreTel;
vector <string> StoreCustomer;
public:
Store(){}
Store(int sid, string sname, string scity, string stown, string stel, string scustomer) {
setStoreID(sid);
setStoreName(sname);
setStoreCity(scity);
setStoreTown(stown);
setStoreTel(stel);
setStoreCustomer(scustomer);
}
void setStoreID(int sid) {
StoreID = sid;
}
void setStoreName(string sname) {
StoreName = sname;
}
void setStoreCity(string scity) {
StoreCity = scity;
}
void setStoreTown(string stown) {
StoreTown = stown;
}
void setStoreTel(string stel) {
StoreTel = stel;
}
void setStoreCustomer(string scustomer) {
StoreCustomer.push_back(scustomer);
}
int getStoreID() {
return StoreID;
}
string getStoreName() {
return StoreName;
}
string getStoreCity() {
return StoreCity;
}
string getStoreTown() {
return StoreTown;
}
string getStoreTel() {
return StoreTel;
}
vector <string> getStoreCustomer() {
return StoreCustomer;
}
~Store(){}
};
Store s2[50];
void AddStore() {
int id, menu;
string name, city, town, tel;
for (int i = 0; i < 1; i++) {
cout << "Lutfen Magaza ID Numarasini Girin: ";
cin >> id;
s2[i].setStoreID(id);
cout << "Lutfen Magaza Adini Girin: ";
cin >> name;
s2[i].setStoreName(name);
cout << "Lutfen Magazanin Bulundugu Ili Girin: ";
cin >> city;
s2[i].setStoreCity(city);
cout << "Lutfen Magazanin Bulundugu Ilceyi Girin: ";
cin >> town;
s2[i].setStoreTown(town);
cout << "Lutfen Magazanin Telefon Numarasini Girin: ";
cin >> tel;
s2[i].setStoreTel(tel);
cout << "Magaza Eklendi" << endl;
cout << "\n\n";
}
cout << "Menuye Donmek icin 0 " << endl;
cin >> menu;
if (menu == 0) {
StoreMenu();
}
else {
cout << "Tanımlanamayan Giris!!!" << endl;
//Menu();
}
}
int Search2(const int& y) {
for (int j = 0; j < 100; j++) {
if (s2[j].getStoreID() == y)
return j;
}
return -1;
}
void AddStoreCustomer() {
int id, found, menu;
string customer;
cout << "Lutfen Musteri Eklemek Istediginiz Magazanin ID Numarasini Girin:";
cin >> id;
found = Search2(id);
if (found == -1)
{
cout << "Magaza Bulunamadi" << endl;
}
else {
cout << "Magaza Bulundu.\n" << "Lutfen Magaza Veri Tabanina Eklemek Istediginiz Musterinin Bilgilerini Girin: ";
cin >> customer;
s2[found].setStoreCustomer(customer);
cout << "Girilen Musteri Bilgisi Secilen Magazaya Eklendi";
cout << "Magaza ID: " << s2[found].getStoreID() << "\n Magaza Adi: " << s2[found].getStoreName() << "\n Magazanin Bulundugu Il: " << s2[found].getStoreCity() << "\n Magazanin Bulundugu Ilce:" << s2[found].getStoreTown() << "\n Magaza Iletisim Numarasi: " << s2[found].getStoreTel() << endl;
cout << "Musteriler: " << endl;
for (int i = 0; i < s2[found].getStoreCustomer().size(); i++)
{
cout << "\t\t" << s2[found].getStoreCustomer()[i] << endl;
}
}
cout << "Tekrar Giris Yapmak icin 1 Menuye Donmek icin 0 " << endl;
cin >> menu;
if (menu == 0) {
StoreMenu();
}
else if (menu == 1) {
AddStoreCustomer();
}
This happens because you are using cin>> to read input, which reads until the first whitespace symbol. If you want to read a whole line, consider using std::getline() instead:
getline(cin, customer);

How to display all the data I entered into my text file?

The following is a code to enter some details of students into a text file and from the main menu, the user can display them using option 2.
My problem is in the section where it should display all the "Taken Courses by student".
When I choose to display all data, the "mentioned section using the for loop only display the last value I enter when writing to the file.
How can I make it display all my entries?
The issue is under the showdata and displaydata functions.
//Project on Student Management
#include<iostream>
#include<fstream>
#include<iomanip>
#include<stdlib.h>
using namespace std;
class Student
{
int id;
int year;
char grade[50];
float cgpa;
int NumberOfcourses;
char courseName[100];
char academic_advisor[100];
char status[100];
public:
void getData();
void showData();
int getID(){return id;}
}s;
void Student::getData()
{
cout<<"\n\nEnter Student Details......\n";
cout<<"Enter ID No. : "; cin>>id;
cout << "Enter Intake Year of the Student: "; cin >> year;
cout << "Enter number of Taken courses: ";
cin >> NumberOfcourses;
for(int a=1; a<=s.NumberOfcourses; a++)
{
cout<<"\nEnter Subject Name: ";
cin.ignore();
cin.getline(courseName, 100);
cout << "Enter Grade of Subject: ";
cin >> grade;
cout<<"\nEnter Subject Status: ";
cin.ignore();
cin.getline(status, 100);
}
cout << "Enter student CGPA: ";
cin >> s.cgpa;
cout << endl;
cout << "Enter Name of Academic Advisor of Student: "; cin.ignore();
cin.getline(s.academic_advisor, 100);
}
void Student::showData()
{
cout << "\n\n.......Student Details......\n";
cout << "ID No. : " << id << endl;
cout << "Intake Year : " << year << endl;
cout << "Subjects Taken in Previous Semester : " << endl;
for(int t=1; t<=NumberOfcourses; t++)
{
cout << "\t" << courseName << ": " << grade << " ("<< status << ") ";
cout << endl;
}
cout << "CGPA : " << cgpa << endl;
cout << "Name of academic advisor of Student : " << academic_advisor << endl;
cout << endl;
}
void addData()
{
ofstream fout;
fout.open("Students.txt", ios::out|ios::app);
s.getData();
fout.write((char*)&s,sizeof(s));
fout.close();
cout<<"\n\nData Successfully Saved to File....\n";
}
void displayData()
{
ifstream fin;
fin.open("Students.txt",ios::in);
while(fin.read((char*)&s,sizeof(s)))
{
s.showData();
}
fin.close();
cout<<"\n\nData Reading from File Successfully Done....\n";
}
void searchData()
{
int n, flag=0;
ifstream fin;
fin.open("Students.txt",ios::in);
cout<<"Enter ID Number you want to search for : ";
cin>>n;
while(fin.read((char*)&s,sizeof(s)))
{
if(n==s.getID())
{
cout<<"The Details of ID No. "<<n<<" are: \n";
s.showData();
flag++;
}
}
fin.close();
if(flag==0)
cout<<"The ID No. "<<n<<" not found....\n\n";
cout<<"\n\nData Reading from File Successfully Done....\n";
}
void deleteData()
{
int n, flag=0;
ifstream fin;
ofstream fout,tout;
fin.open("Students.txt",ios::in);
fout.open("TempStud.txt",ios::out|ios::app);
tout.open("TrashStud.txt",ios::out|ios::app);
cout<<"Enter ID Number you want to delete : ";
cin>>n;
while(fin.read((char*)&s,sizeof(s)))
{
if(n==s.getID())
{
cout<<"The Following ID No. "<< n <<" has been deleted:\n";
s.showData();
tout.write((char*)&s,sizeof(s));
flag++;
}
else
{
fout.write((char*)&s,sizeof(s));
}
}
fout.close();
tout.close();
fin.close();
if(flag==0)
cout<<"The ID No. "<< n <<" not found....\n\n";
remove("Students.dat");
rename("tempStud.txt","Students.txt");
}
void modifyData()
{
int n, flag=0, pos;
fstream fio;
fio.open("Students.txt", ios::in|ios::out);
cout<<"Enter ID Number you want to Modify : ";
cin>>n;
while(fio.read((char*)&s,sizeof(s)))
{
pos=fio.tellg();
if(n==s.getID())
{
cout<<"The Following ID No. "<<n<<" will be modified with new data:\n";
s.showData();
cout<<"\n\nNow Enter the New Details....\n";
s.getData();
fio.seekg(pos-sizeof(s));
fio.write((char*)&s,sizeof(s));
flag++;
}
}
fio.close();
if(flag==0)
cout<<"The ID No. "<<n<<" not found....\n\n";
}
void project()
{
int ch;
do
{
system("cls");
cout<<"...............STUDENT MANAGEMENT SYSTEM..............\n";
cout<<"======================================================\n";
cout<<"0. Exit from Program\n";
cout<<"1. Write Data to File\n";
cout<<"2. Read Data From File\n";
cout<<"3. Search Data From File\n";
cout<<"4. Delete Data From File\n";
cout<<"5. Modify Data in File\n";
cout<<"Enter your choice : ";
cin>>ch;
system("cls");
switch(ch)
{
case 1: addData(); break;
case 2: displayData(); break;
case 3: searchData(); break;
case 4: deleteData(); break;
case 5: modifyData(); break;
}
system("pause");
}while(ch);
}
int main()
{
project();
}
Console Display with problem
Your Student class can only hold 1 set of course information. Your getData() loop is overwriting the same variables over and over, that is why you only see the last course entered. You need to allocate an array (or better, use a std::vector) to hold multiple courses per Student.
There are other problems with your code as well.
Try something more like this instead:
//Project on Student Management
#include <iostream>
#include <fstream>
using namespace std;
struct Course
{
char courseName[100];
char grade[50];
char status[100];
};
class Student
{
int id;
int year;
float cgpa;
int NumberOfcourses;
Course *courses;
char academic_advisor[100];
public:
Student();
~Student();
void getData();
void showData() const;
int getID() const { return id; }
friend ostream& operator<<(ostream &out, const Student &s);
friend istream& operator>>(istream &in, Student &s);
};
ostream& operator<<(ostream &out, const Course &c)
{
out.write(c.courseName, sizeof(c.courseName));
out.write(c.grade, sizeof(c.grade));
out.write(c.status, sizeof(c.status));
return out;
}
istream& operator>>(istream &in, Course &c)
{
in.read(c.courseName, sizeof(c.courseName));
in.read(c.grade, sizeof(c.grade));
in.read(c.status, sizeof(c.status));
return in;
}
ostream& operator<<(ostream &out, const Student &s)
{
out.write((char*)&s.id, sizeof(s.id));
out.write((char*)&s.year, sizeof(s.year));
out.write((char*)&s.cgpa, sizeof(s.cgpa));
out.write(s.academic_advisor, sizeof(s.academic_advisor));
out.write((char*)&s.NumberOfcourses, sizeof(s.NumberOfcourses));
for(int i = 0; i < s.NumberOfcourses; ++i)
{
out << s.courses[i];
}
return out;
}
istream& operator>>(istream &in, Student &s)
{
delete[] s.courses;
s.courses = NULL;
s.NumberOfcourses = 0;
in.read((char*)&s.id, sizeof(s.id));
in.read((char*)&s.year, sizeof(s.year));
in.read((char*)&s.cgpa, sizeof(s.cgpa));
in.read(s.academic_advisor, sizeof(s.academic_advisor));
int NumberOfcourses;
if (in.read((char*)&NumberOfcourses, sizeof(NumberOfcourses)))
{
s.courses = new Course[NumberOfcourses];
for(int i = 0; i < NumberOfcourses; ++i)
{
if (in >> s.courses[i])
s.NumberOfcourses++;
else
break;
}
}
return in;
}
Student::Student()
{
id = 0;
year = 0;
cgpa = 0.0f;
NumberOfcourses = 0;
courses = NULL;
academic_advisor[0] = '\0';
}
Student::~Student()
{
delete[] courses;
}
void Student::getData()
{
cout << "\n\nEnter Student Details......\n";
cout << "Enter ID No. : "; cin >> id;
cout << "Enter Intake Year of the Student: "; cin >> year;
cout << "Enter number of Taken courses: ";
cin >> NumberOfcourses;
cin.ignore();
delete[] courses;
courses = new Course[NumberOfcourses];
for(int a = 0; a < NumberOfcourses; ++a)
{
cout << "\nEnter Subject Name: ";
cin.getline(courses[a].courseName, 100);
cout << "Enter Grade of Subject: ";
cin.getline(courses[a].grade, 50);
cout << "\nEnter Subject Status: ";
cin.getline(courses[a].status, 100);
}
cout << "Enter student CGPA: ";
cin >> cgpa;
cin.ignore();
cout << endl;
cout << "Enter Name of Academic Advisor of Student: ";
cin.getline(academic_advisor, 100);
}
void Student::showData() const
{
cout << "\n\n.......Student Details......\n";
cout << "ID No. : " << id << endl;
cout << "Intake Year : " << year << endl;
cout << "Subjects Taken in Previous Semester : " << endl;
for(int t = 0; t < NumberOfcourses; ++t)
{
cout << "\t" << courses[t].courseName << ": " << courses[t].grade << " (" << courses[t].status << ") ";
cout << endl;
}
cout << "CGPA : " << cgpa << endl;
cout << "Name of academic advisor of Student : " << academic_advisor << endl;
cout << endl;
}
void addData()
{
Student s;
s.getData();
ofstream fout("Students.txt", ios::binary|ios::app);
if (fout << s)
cout << "\n\nData Successfully Saved to File....\n";
else
cerr << "\n\nError Saving Data to File!\n";
}
void displayData()
{
ifstream fin("Students.txt", ios::binary);
Student s;
while (fin >> s)
{
s.showData();
}
if (!fin)
cerr << "\n\nError Reading Data from File!\n";
else
cout << "\n\nData Reading from File Successfully Done....\n";
}
void searchData()
{
int n;
cout << "Enter ID Number you want to search for : ";
cin >> n;
ifstream fin("Students.txt", ios::binary);
Student s;
bool flag = false;
while (fin >> s)
{
if (n == s.getID())
{
cout << "The Details of ID No. " << n << " are: \n";
s.showData();
flag = true;
break;
}
}
if (!fin)
{
cerr << "\n\nError Reading Data from File!\n";
}
else
{
if (!flag)
cout << "The ID No. " << n << " not found....\n\n";
cout << "\n\nData Reading from File Successfully Done....\n";
}
}
void deleteData()
{
int n;
cout << "Enter ID Number you want to delete : ";
cin >> n;
ifstream fin("Students.txt", ios::binary);
ofstream fout("TempStud.txt", ios::binary);
ofstream tout("TrashStud.txt", ios::binary|ios::app);
Student s;
bool flag = false;
while (fin >> s)
{
if (n == s.getID())
{
cout << "The Following ID No. " << n << " will be deleted:\n";
s.showData();
tout << s;
flag = true;
}
else
{
fout << s;
}
}
if (!fin)
{
cerr << "\n\nError Reading Data from File!\n";
}
else if (!fout)
{
cerr << "\n\nError Saving Data to File!\n";
}
else
{
fin.close();
fout.close();
if (!flag)
{
cout << "The ID No. " << n << " not found....\n\n";
remove("tempStud.txt");
}
else
{
remove("Students.txt");
rename("tempStud.txt", "Students.txt");
cout << "\n\nData Successfully Deleted from File....\n";
}
}
}
void modifyData()
{
int n;
cout << "Enter ID Number you want to Modify : ";
cin >> n;
ifstream fin("Students.txt", ios::binary);
ofstream fout("TempStud.txt", ios::binary);
Student s;
bool flag = false;
while (fin >> s)
{
if (n == s.getID())
{
cout << "The Following ID No. " << n << " will be modified with new data:\n";
s.showData();
cout << "\n\nNow Enter the New Details....\n";
s.getData();
flag = true;
}
fout << s;
}
if (!fin)
{
cerr << "\n\nError Reading Data from File!\n";
}
else if (!fout)
{
cerr << "\n\nError Saving Data to File!\n";
}
else
{
fin.close();
fout.close();
if (!flag)
{
cout << "The ID No. " << n << " not found....\n\n";
remove("TempStud.txt");
}
else
{
remove("Students.txt");
rename("TempStud.txt", "Students.txt");
cout << "\n\nData Successfully Updated in File....\n";
}
}
}
void project()
{
int ch;
do
{
system("cls");
cout << "...............STUDENT MANAGEMENT SYSTEM..............\n";
cout << "======================================================\n";
cout << "0. Exit from Program\n";
cout << "1. Write Data to File\n";
cout << "2. Read Data From File\n";
cout << "3. Search Data From File\n";
cout << "4. Delete Data From File\n";
cout << "5. Modify Data in File\n";
cout << "Enter your choice : ";
cin >> ch;
system("cls");
switch (ch)
{
case 1: addData(); break;
case 2: displayData(); break;
case 3: searchData(); break;
case 4: deleteData(); break;
case 5: modifyData(); break;
}
system("pause");
}
while (ch != 0);
}
int main()
{
project();
}
Alternatively:
//Project on Student Management
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
struct Course
{
string courseName;
string grade;
string status;
};
class Student
{
int id;
int year;
float cgpa;
vector<Course> courses;
string academic_advisor;
public:
Student();
void getData();
void showData() const;
int getID() const { return id; }
friend ostream& operator<<(ostream &out, const Student &s);
friend istream& operator>>(istream &in, Student &s);
};
void writeStr(ostream &out, const string &str)
{
size_t size = str.size();
out.write((char*)&size, sizeof(size));
if (size)
out.write(str.c_str(), size);
}
void readStr(istream &in, string &str)
{
str.clear();
size_t size;
if (in.read((char*)&size, sizeof(size)))
{
if (size > 0)
{
str.resize(size);
in.read(&str[0], size);
}
}
}
ostream& operator<<(ostream &out, const Course &c)
{
writeStr(out, c.courseName);
writeStr(out, c.grade);
writeStr(out, c.status);
return out;
}
istream& operator>>(istream &in, Course &c)
{
readStr(in, c.courseName);
readStr(in, c.grade);
readStr(in, c.status);
return in;
}
ostream& operator<<(ostream &out, const Student &s)
{
out.write((char*)&s.id, sizeof(s.id));
out.write((char*)&s.year, sizeof(s.year));
out.write((char*)&s.cgpa, sizeof(s.cgpa));
writeStr(out, s.academic_advisor);
size_t NumberOfcourses = s.courses.size();
out.write((char*)&NumberOfcourses, sizeof(NumberOfcourses));
for(int i = 0; i < NumberOfcourses; ++i)
{
if (!(out << s.courses[i]))
break;
}
return out;
}
istream& operator>>(istream &in, Student &s)
{
s.courses.clear();
in.read((char*)&s.id, sizeof(s.id));
in.read((char*)&s.year, sizeof(s.year));
in.read((char*)&s.cgpa, sizeof(s.cgpa));
readStr(in, s.academic_advisor);
size_t NumberOfcourses;
if (in.read((char*)&NumberOfcourses, sizeof(NumberOfcourses)))
{
s.courses.reserve(NumberOfcourses);
Course c;
for(size_t i = 0; i < NumberOfcourses; ++i)
{
if (in >> c)
s.courses.push_back(c);
else
break;
}
}
return in;
}
Student::Student()
{
id = 0;
year = 0;
cgpa = 0.0f;
}
void Student::getData()
{
courses.clear();
cout << "\n\nEnter Student Details......\n";
cout << "Enter ID No. : "; cin >> id;
cout << "Enter Intake Year of the Student: "; cin >> year;
cout << "Enter number of Taken courses: ";
size_t NumberOfcourses;
cin >> NumberOfcourses;
cin.ignore();
courses.reserve(NumberOfcourses);
Course c;
for(int a = 0; a < NumberOfcourses; ++a)
{
cout << "\nEnter Subject Name: ";
getline(cin, c.courseName);
cout << "Enter Grade of Subject: ";
getline(cin, c.grade);
cout << "\nEnter Subject Status: ";
getline(cin, c.status);
s.courses.push_back(c);
}
cout << "Enter student CGPA: ";
cin >> cgpa;
cin.ignore();
cout << endl;
cout << "Enter Name of Academic Advisor of Student: ";
getline(cin, academic_advisor);
}
void Student::showData() const
{
cout << "\n\n.......Student Details......\n";
cout << "ID No. : " << id << endl;
cout << "Intake Year : " << year << endl;
cout << "Subjects Taken in Previous Semester : " << endl;
for(size_t t = 0; t < courses.size(); ++t)
{
cout << "\t" << courses[t].courseName << ": " << courses[t].grade << " (" << courses[t].status << ") ";
cout << endl;
}
cout << "CGPA : " << cgpa << endl;
cout << "Name of academic advisor of Student : " << academic_advisor << endl;
cout << endl;
}
void addData()
{
Student s;
s.getData();
ofstream fout("Students.txt", ios::binary|ios::app);
if (fout << s)
cout << "\n\nData Successfully Saved to File....\n";
else
cerr << "\n\nError Saving Data to File!\n";
}
void displayData()
{
ifstream fin("Students.txt", ios::binary);
Student s;
while (fin >> s)
{
s.showData();
}
if (!fin)
cerr << "\n\nError Reading Data from File!\n";
else
cout << "\n\nData Reading from File Successfully Done....\n";
}
void searchData()
{
int n;
cout << "Enter ID Number you want to search for : ";
cin >> n;
ifstream fin("Students.txt", ios::binary);
Student s;
bool flag = false;
while (fin >> s)
{
if (n == s.getID())
{
cout << "The Details of ID No. " << n << " are: \n";
s.showData();
flag = true;
break;
}
}
if (!fin)
{
cerr << "\n\nError Reading Data from File!\n";
}
else
{
if (!flag)
cout << "The ID No. " << n << " not found....\n\n";
cout << "\n\nData Reading from File Successfully Done....\n";
}
}
void deleteData()
{
int n;
cout << "Enter ID Number you want to delete : ";
cin >> n;
ifstream fin("Students.txt", ios::binary);
ofstream fout("TempStud.txt", ios::binary);
ofstream tout("TrashStud.txt", ios::binary|ios::app);
Student s;
bool flag = false;
while (fin >> s)
{
if (n == s.getID())
{
cout << "The Following ID No. " << n << " will be deleted:\n";
s.showData();
tout << s;
flag = true;
}
else
{
fout << s;
}
}
if (!fin)
{
cerr << "\n\nError Reading Data from File!\n";
}
else if (!fout)
{
cerr << "\n\nError Saving Data to File!\n";
}
else
{
fin.close();
fout.close();
if (!flag)
{
cout << "The ID No. " << n << " not found....\n\n";
remove("tempStud.txt");
}
else
{
remove("Students.txt");
rename("tempStud.txt", "Students.txt");
cout << "\n\nData Successfully Deleted from File....\n";
}
}
}
void modifyData()
{
int n;
cout << "Enter ID Number you want to Modify : ";
cin >> n;
ifstream fin("Students.txt", ios::binary);
ofstream fout("TempStud.txt", ios::binary);
Student s;
bool flag = false;
while (fin >> s)
{
if (n == s.getID())
{
cout << "The Following ID No. " << n << " will be modified with new data:\n";
s.showData();
cout << "\n\nNow Enter the New Details....\n";
s.getData();
flag = true;
}
fout << s;
}
if (!fin)
{
cerr << "\n\nError Reading Data from File!\n";
}
else if (!fout)
{
cerr << "\n\nError Saving Data to File!\n";
}
else
{
fin.close();
fout.close();
if (!flag)
{
cout << "The ID No. " << n << " not found....\n\n";
remove("TempStud.txt");
}
else
{
remove("Students.txt");
rename("TempStud.txt", "Students.txt");
cout << "\n\nData Successfully Updated in File....\n";
}
}
}
void project()
{
int ch;
do
{
system("cls");
cout << "...............STUDENT MANAGEMENT SYSTEM..............\n";
cout << "======================================================\n";
cout << "0. Exit from Program\n";
cout << "1. Write Data to File\n";
cout << "2. Read Data From File\n";
cout << "3. Search Data From File\n";
cout << "4. Delete Data From File\n";
cout << "5. Modify Data in File\n";
cout << "Enter your choice : ";
cin >> ch;
system("cls");
switch (ch)
{
case 1: addData(); break;
case 2: displayData(); break;
case 3: searchData(); break;
case 4: deleteData(); break;
case 5: modifyData(); break;
}
system("pause");
}
while (ch != 0);
}
int main()
{
project();
}

Unable to return struct value in c++

I have two text files and the Load function transfers the data from both text files to a single struct (Employee emp[length]) with a const length of 2001. This is because there are 2000 employee details in the text file.
After loading the data into struct, I wanted to search and display employee data using the Select function.
The user will be prompted to choose which employee attribute and keyword that is going to be used for searching. However, I realize that I cannot return a struct(emp[i]) or a string value(emp[i].empId). It will prompt out an error saying
access violation reading location 0x00D2C000
However, I am able to display the string value(emp[i].empId) using cout.
May I know why can I cout the string value but not return it?
Thank you for your help in advance and sorry for my poor English.
const int length = 2001;
struct Employee {
string empId;
string dOB;
string height;
string weight;
string yrOfWork;
string salary;
string allowance;
string name;
string country;
string designation;
string gender;
string lvlOfEdu;
};
Employee emp[length];
void Load();
Employee Select(int k, string s, int c);
int main() {
bool quit = false;
int option;
while (quit != true) { //loop the program unless 7 is chosen
Load();
cout << "1. Add" << endl; //
cout << "2. Delete" << endl;
cout << "3. Select" << endl;
cout << "4. Advanced Search" << endl;
cout << "5. Standard Deviation" << endl;
cout << "6. Average" << endl;
cout << "7. Quit" << endl;
cout << "Please key in an option: ";
cin >> option;
system("cls"); //to refresh the screen
switch (option) {
case 3: {
int search;
string key;
cout << "1. Employee ID" << endl;
cout << "2. Date of Birth" << endl;
cout << "3. Height" << endl;
cout << "4. Weight" << endl;
cout << "5. Years of Working" << endl;
cout << "6. Basic Salary" << endl;
cout << "7. Allowance" << endl;
cout << "8. Employee Name" << endl;
cout << "9. Country" << endl;
cout << "10. Designation" << endl;
cout << "11. Gender" << endl;
cout << "12. Level of Education" << endl;
cout << "Select By: ";
cin >> search;
cout << "Enter keyword: ";
cin >> key;
for (int i = 0; i < length; i++) {
cout << Select(search, key, i).empId;
}
system("pause");
system("cls");
break;
}
}
}
}
Employee Select(int s, string k, int c) {
int result;
int i = c;
switch(s) {
case 1:
result = emp[i].empId.find(k);
if (result >= 0) {
return emp[i];
}
break;
}
}
void Load() {
ifstream inFigures;
inFigures.open("profiles_figures.txt");
ifstream inWords;
inWords.open("profiles_words.txt");
if (inFigures.is_open()) {
int i = 0;
while (!inFigures.eof()) {
inFigures >> emp[i].empId;
inFigures.ignore();
inFigures >> emp[i].dOB;
inFigures.ignore();
inFigures >> emp[i].height;
inFigures.ignore();
inFigures >> emp[i].weight;
inFigures.ignore();
inFigures >> emp[i].yrOfWork;
inFigures.ignore();
inFigures >> emp[i].salary;
inFigures.ignore();
inFigures >> emp[i].allowance;
inFigures.ignore();
i++;
}
}
//inFigures.close();
if (inWords.is_open()) {
int i = 0;
while (!inWords.eof()) {
getline(inWords, emp[i].name);
getline(inWords, emp[i].country);
getline(inWords, emp[i].designation);
inWords >> emp[i].gender;
inWords.ignore();
inWords >> emp[i].lvlOfEdu;
inWords.ignore();
i++;
}
}
//inWords.close();
}
The main problem I think is, what do you return if Select doesn't find anything? The function is supposed to return an employee. You could have a special Employee with a nonsensical empId (e.g. -1) to indicate this, and change
for (int i = 0; i < length; i++)
{
cout << Select(search, key, i).empId;
}
to
for (int i = 0; i < length; i++)
{
Employee selected = Select(search, key, i);
if (selected.empId != -1)
{
cout << Select(search, key, i).empId;
}
}
Alternatively you could alter the Select function so that it returns a pointer Employee * and then return nullptr if there is no match. That is
Employee* Select(int s, string k, int c)
{
int result;
int i = c; // why not just use c directly? Or change the argument to int i?
switch(s)
{
case 1:
result = emp[i].empId.find(k);
if (result >= 0)
{
return &emp[i]; // note taking address, could also write emp + i
}
break; // don't need this with no further cases
}
return nullptr; // reached if no match above
}
Followed later by
for (int i = 0; i < length; i++)
{
Employee* selected = Select(search, key, i);
if (selected != nullptr)
{
cout << Select(search, key, i)->empId; // not pointer indirection
}
}
Really you'd probably want to return a const Employee const*, but that's another topic.
Yet another option is having Select throw an exception if it doesn't find anything, and placing the call to Select(search, key, i); in a try .. catch block. I generally prefer not to use exceptions for control flow like this, but it is another method.

How to add new row to a vector using struct in C++

Hello I am having issues with a final project. The objective is to have the user create a form that allows a user to view data, edit data, add data, and save their password data in an encoded format. The program starts with an input file made by the user. The delimiter is ';', and the first char is a "code", then the, site, username, password, and notes follow.
I am very new to vectors, and I am not allowed to use a 2d array, or map.
Thank you for your time.
#include <iomanip>
#include <cmath>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
const int MAX_SIZE = 30;
const int BUFFER_SIZE = 200;
struct dataRow {
string site, user, pass, notes;
string code;
};
string inFileName; //name of inputfile
string outFileName;
ifstream pathStream;
ofstream outFile;
char inputChar;
int extPosition(1), count = 0,lineNum;
void displayVector(vector<dataRow> inputData);
void viewLineData(vector<dataRow> inputData, int lineNum);
void addNewRow(vector<dataRow> inputData,int& lastRowNum, string site, string user, string pass, string notes);
void editLineData(vector<dataRow> inputData, int& lineNum, string site, string user, string pass, string notes);
void warning();
void cleanBuffer();
bool displayMenu();
int exit();
dataRow descripLine;
int main()
{
vector<dataRow> inputData;
string rowDescripin,userin,passin,notesin,sitein;
string codein,errorMsg;
int lastRow;
//add a .txt extension to the file if the user didn't provide an extension
if (inFileName.size() > 4)
// If there's a valid extension, it will be in the last 4 positions of the string; Adjust by 1 for 0 offset
extPosition = inFileName.size() - 4;
int ext = inFileName.find_last_of(".txt");
if (!(inFileName.find_last_of(".") == extPosition))
{
inFileName += ".txt";
}
cout << "\nPlease enter the filename of input file: ";
cin >> inFileName;
pathStream.open(inFileName.c_str());
if (pathStream.fail())
{
cerr << inFileName << " failed to open.\n";
system("pause");
exit(1);
}
else
{
cout << "startup success" << endl;
}
getline(pathStream, codein, ';');
descripLine.code = codein;
while (!pathStream.eof())
{
getline(pathStream, sitein, ';');
descripLine.site = sitein;
getline(pathStream, userin, ';');
descripLine.user = userin;
getline(pathStream, passin, ';');
descripLine.pass = passin;
getline(pathStream, notesin, ';');
descripLine.notes = notesin;
inputData.push_back(descripLine);
}
displayVector(inputData);
displayMenu();
while (cin){
cin >> inputChar;
inputChar = toupper(inputChar);
//Adjust calculations based on inputCHar
if (inputChar == 'D') // Display line descriptions
{
displayVector(inputData);
}
else if (inputChar == 'V') //View line data
{
cout << "Enter line number you wish to view: ";
cin >> lineNum;
viewLineData(inputData, lineNum);
}
/* else if (inputChar == 'E') //Edit line Data
{
cout << "Enter line number you wish to edit: ";
cin >> lineNum;
editLineData(inputData, lineNum);
}*/
else if (inputChar == 'A') //Add line data
{
warning();
lastRow = inputData.size();
cout << "Enter a line description: ";
cin >> rowDescripin;
cout << "Enter a line username: ";
cin >> userin;
cout << "Enter a line password: ";
cin>>passin;
cout << "Enter notes: ";
cin>>notesin;
addNewRow(inputData, lastRow, rowDescripin, userin, passin, notesin);
}
/*else if (inputChar == 'S') //Save and encode file
{
}*/
else if (inputChar == 'X') //exit program
{
exit();
}
}
system("pause");
}
bool displayMenu()
{
cout << endl << " AVAILABLE OPTIONS " << endl << endl <<
"D - DISPLAY LINE DESCRIPTIONS" << endl <<
"V - VIEW LINE DATA" << endl <<
"E - EDIT LINE DATA" << endl <<
"A - ADD LINE DATA" << endl <<
"S - SAVE AND ENCODE FILE" << endl <<
"X - EXIT PROGRAM" << endl;
return 0;
}
void viewLineData(vector<dataRow> inputData,int lineNum)
{
cout << inputData[lineNum].site << endl << inputData[lineNum].user<<endl<<inputData[lineNum].pass <<endl<<inputData[lineNum].notes;
}
void displayVector(vector<dataRow> inputData)
{
cout << fixed << setprecision(3);
for (unsigned int i = 0; i < inputData.size(); i++)
{
cout << left << setw(20) << inputData[i].site ;
}
}
void addNewRow(vector<dataRow> inputData, int& lastRowNum, string site, string user, string pass, string notes)
{
char ans;
cout << "You have entered:" << endl << site << endl << user << endl << pass << endl << notes<<endl;
cout << "Is this the data you wish to add (Y/N)? ";
cin >> ans;
ans = toupper(ans);
if (ans == 'Y')
{
dataRow tempRow = { site, user, pass, notes };
inputData.push_back(tempRow);
cout << inputData.size();
int num = inputData.size()-1;
for (unsigned int i = 0; i < inputData.size(); i++)
{
cout << inputData[i].site << endl << inputData[i].user << endl << inputData[i].pass << endl << inputData[i].notes;
}
}
else if (ans == 'N')
{
cout << "ok enter of no";
}
}
void warning()
{
cout<< "WARNING: You cannot use semi-colons in these fields. Any semi-colons entered will be removed." << endl;
return;
}
int exit()
{
pathStream.close();
system("pause");
return 0;
}
void cleanBuffer()
{
cin.clear();
cin.ignore(BUFFER_SIZE, '\n');
}

Deleting a record from text file

I have got an assignment project to make a program using C++ which maintains a list of Students (their name, age, and GPA) in a text file. The program has the following functionality:
Insertion of record
Deletion of record
Searching of record
Updating a record
When deleting a record my code takes a string name as input and removes it from the text file. However the next two lines in the file (age & gpa for that student) are left. How do I remove those too?
Following is the code for my program.
#include <iostream>
#include <fstream>
using namespace std;
void writing();
void deleting();
void searching();
class student {
public:
int age = 0;
string name;
void SetGpa(float x)
{
gpa = x;
}
float GetGpa()
{
return gpa;
}
private:
float gpa = 0.0;
};
int main()
{
int opt;
cout << "Please Enter an option number to continue:\n ";
cout << "\nPress 1 for New Record insertion";
cout << "\nPress 2 for Record Deletion";
cout << "\nPress 3 for Searching a Record";
cout << "\nPress 4 for Updating a Record";
cout << "\nEnter option Number: ";
cin >> opt;
switch (opt)
{
case 1:
{
writing();
break;
}
case 2:
{
deleting();
break;
}
case 3:
{
searching();
break;
}
case 4:
{
deleting();
writing();
cout << "Record has been updated! ";
break;
}
}
}
void writing()
{
float a;
student moiz;
cout << "Please enter name of student: ";
cin >> moiz.name;
cout << "Please enter the age of student: ";
cin >> moiz.age;
cout << "Pleae enter the Gpa of student: ";
cin >> a;
moiz.SetGpa(a);
ofstream myfile;
myfile.open("record.txt", ios::app | ios::out);
myfile << endl << moiz.name << endl;
myfile << moiz.age << endl;
myfile << moiz.GetGpa();
myfile.close();
}
void deleting()
{
string line, name;
cout << "Please Enter the name of record you want to delete: ";
cin >> name;
ifstream myfile;
ofstream temp;
myfile.open("record.txt");
temp.open("temp.txt");
while (getline(myfile, line))
{
if (line != name)
temp << line << endl;
}
cout << "The record with the name " << name << " has been deleted if it exsisted" << endl;
myfile.close();
temp.close();
remove("record.txt");
rename("temp.txt", "record.txt");
}
void searching()
{
ifstream fileInput;
fileInput.open("record.txt");
string line, search;
cout << "Please enter the term to search: ";
cin >> search;
for (unsigned int curLine = 0; getline(fileInput, line); curLine++)
{
if (line.find(search) != string::npos)
{
cout << "found: " << search << " on line: " << curLine << endl;
}
else
{
cout << "Error! Not found on Line" << curLine << endl;
}
}
}
You can add an else clause to your statement checking the name, and introduce a counter of how many of the following lines should be skipped after name was found:
int skip = 0;
while (getline(myfile, line)) {
if ((line != name) && !(skip > 0)) {
temp << line << endl;
}
else {
if(skip == 0) {
skip = 2; // Skip the next two lines also
}
else {
--skip;
}
}
}