Outputting Vector of Type Class - c++

There is more code to this question in this previous question: C++ Trouble Inputting Data into Private Vector (invalid use)
I'm trying to output a vector of type "Account"
Account:
class Account
{
string firstName;
string lastName;
string accountPass;
int accountID;
float accountBalance;
private:
int depositAmount;
int withdrawAmount;
public:
static Account createAccount( int, float, string, string, string ); //creates new account
void deposit( int ); //deposits money into account
void withdraw(int); //withdrawals money from account
int retdeposit() const; //function to return balance amount
friend class BankingSystem;
}; //end of class Account
This is the way I'm declaring the vector:
std::vector<Account> accounts_;
And here's how I'm trying to print it to the screen:
for(int i=0; i < accounts_.size(); i++)
{ cout<< accounts_[i] <<endl; }
But I'm getting this error "invalid operands to binary expression".
Current code;
class BankingSystem
{
int accountID;
char fileName;
private:
std::vector<Account> accounts_;
public:
void addAccount();
void storeAccount( Account );
void deleteAccount();
void accountInquiry();
void saveAccounts();
void loadAccountsFromFile();
friend class Account;
friend std::ostream& operator << (std::ostream&, const Account&);
}; // end of class BankingSystem
#endif
std::ostream& operator << (std::ostream& os, const Account& acc)
{
// output members to os
return os;
}
void BankingSystem::addAccount()
{
int ID;
float balance;
std::string pass, first, last;
cout << "\n\t Enter the Account ID: ";
cin >> ID;
cout << "\n\t Enter the passcode: ";
cin >> pass;
cout << "\n\t Enter Client's first name: ";
cin >> first;
cout << "\n\t Enter Client's last name: ";
cin >> last;
cout << "\n\t Enter starting balance: ";
cin >> setw(6) >> balance;
storeAccount( Account::createAccount( ID, balance, pass, first, last ) );
return;
}
//function gets data from createAccount
void BankingSystem::storeAccount( Account newAccountToAdd )
{
//append to vector "accounts_"
accounts_.push_back(newAccountToAdd);
}
void BankingSystem::deleteAccount()
{
cout << "\nEnter The Account ID: ";
cin >> accountID;
}
void BankingSystem::accountInquiry()
{
int n;
cout << "\n\t Enter The Account ID (-1 for all): ";
cin >> n;
//cout << accounts_.size();
if (n == -1)
{
cout << "\n\t List of all Accounts; (" << accounts_.size() << ") TOTAL: ";
for(int i=0; i < accounts_.size(); i++)
{
cout<< accounts_[i] << endl;
}
}
else
{
cout << "\n\t Listing Account: " << n;
cout << "\n\t I should search the vector for the ID you input";
}
}

You need to provide the insertion operator:
std::ostream& operator<<( std::ostream& out, const Account& acct );
Then implement it internally by dumping each one of the fields with the appropriate format.

You should overload operator << for Account class. In class:
friend std::ostream& operator << (std::ostream&, const Account&);
In global (or yours, where Account is defined) namespace
std::ostream& operator << (std::ostream& os, const Account& acc)
{
// output members to os
return os;
}
or create some output function in class for example
void print(std::ostream& os) const { }
And then free-operator <<
std::ostream& operator << (std::ostream& os, const Account& acc)
{
acc.print(os);
return os;
}

Related

How to print a string from an object?

I tried the below code to write an object to a dat file:
#include<iostream>
#include<fstream>
#include<string>
#include<string.h>
using namespace std;
class Student
{ //data members
int adm;
string name;
public:
Student()
{
adm = 0;
name = "";
}
Student(int a,string n)
{
adm = a;
name = n;
}
Student setData(Student st) //member function
{
cout << "\nEnter admission no. ";
cin >> adm;
cout << "Enter name of student ";
cin.ignore();
getline(cin,name);
st = Student(adm,name);
return st;
}
void showData()
{
cout << "\nAdmission no. : " << adm;
cout << "\nStudent Name : " << name;
}
int retAdmno()
{
return adm;
}
};
/*
* function to write in a binary file.
*/
void demo()
{
ofstream f;
f.open("student.dat",ios::binary);
for(int i = 0;i<4;i++)
{
Student st;
st = st.setData(st);
f.write((char*)&st,sizeof(st));
}
f.close();
ifstream fin;
fin.open("student.dat",ios::binary);
Student st;
while(!fin.eof())
{
fin.read((char*)&st,sizeof(st));
st.showData();
}
}
int main()
{
demo();
return 0;
}
But when I am executing the demo function I am getting some garbage values from the "student.dat"
file. I am creating a database and want to get the records but I am not able to get all the records in the dat file.
Please suggest a solution
You cannot write complex data types to a file in binary mode. They have some additional variables and functions inside,which you do not know or see. Those data types have some internal state that or context dependent. So, you cannot store in binary and then reuse it somewhere else. That will never work.
The solution is serialization/deserialization.
This sounds complicated, but is not at all in your case. It basically means that all your data from your struct shall be converted to plain text and put in a text-file.
For readin the data back, it will be first read as text, and then converted to your internal data structures.
And the default approach for that is to overwrite the inserter << operator and extractor >> operator.
See the simple example in your modified code:
#include<iostream>
#include<fstream>
#include<string>
#include<iomanip>
class Student
{ //data members
int adm;
std::string name;
public:
Student()
{
adm = 0;
name = "";
}
Student(int a, std::string n)
{
adm = a;
name = n;
}
Student setData(Student st) //member function
{
std::cout << "\nEnter admission no. ";
std::cin >> adm;
std::cout << "Enter name of student ";
std::getline(std::cin>> std::ws, name);
st = Student(adm, name);
return st;
}
void showData()
{
std::cout << "\nAdmission no. : " << adm;
std::cout << "\nStudent Name : " << name;
}
int retAdmno()
{
return adm;
}
friend std::ostream& operator << (std::ostream& os, const Student& s) {
return os << s.adm << '\n' << s.name << '\n';
}
friend std::istream& operator >> (std::istream& is, Student& s) {
return std::getline(is >> s.adm >> std::ws, s.name);
}
};
/*
* function to write in a binary file.
*/
void demo()
{
std::ofstream f("student.dat");
for (int i = 0; i < 4; i++)
{
Student st;
st = st.setData(st);
f << st;
}
f.close();
std::ifstream fin("student.dat");
Student st;
while (!fin.eof())
{
fin >> st;
st.showData();
}
}
int main()
{
demo();
return 0;
}

How to make function "run" work. The program just exits when run is called

I'm trying to make a login system (in progress) for a challenge(self), but the function "run" that returns a function, exits when called. Kindly assist
#include <iostream>
#include <string>
#include <array>
#include <vector>
using namespace std;
//initialise function pointer that is void and takes no parameter
typedef void (*funcpointer)();
//forward declare a function run that takes an integer parameter
funcpointer run(int op);
//declare class user with username and password
class User {
private:
string m_name;
string m_password;
public:
//constructor for class
User()
{
}
//friend functions that need to access class members
friend istream& operator>>(istream& in, User& user);
friend ostream& operator<<(ostream& out, User& user);
friend void access();
friend void display();
};
//vector that stores class
std::vector<User> m_user;
//allows user defined input of class members
istream& operator>>(istream& in, User& user)
{
cout << "Enter your username: ";
in >> user.m_name;
cout << "Enter your password: ";
in >> user.m_password;
return in;
}
//ouputs Class member contents in user defined manner(allows cout << class)
ostream& operator<<(ostream& out, User& user)
{
out << "Username is: " << user.m_name << " Password is: " << user.m_password << '\n';
return out;
}
//allows user to choose whether to log in, make ne user or view users
void logIn()
{
int num;
cout << "Would you like to: \n1: Make new user\n2: Log In\n3: Display users\n";
do {
cin >> num;
} while ((num != 1) && (num != 2) && (num != 3));
run(num);
}
void newUser()
{
User x;
cin >> x;
m_user.push_back(x);
}
void access()
{
string name, password;
cout << "Enter username: ";
getline(cin, name);
for (size_t i = 0; i < m_user.size(); i++) {
if (name == m_user[i].m_name) {
cout << m_user[i].m_name << " found. Enter password: ";
getline(cin, password);
if (password == m_user[i].m_password) {
cout << "access granted";
}
else
cout << "Wrong password\n";
}
else
cout << "Username not found!\n";
}
}
void display()
{
int count = 1;
for (auto& users : m_user) {
cout << count << ": " << users.m_name << '\n';
}
}
//function run that returns function
funcpointer run(int op)
{
switch (op) {
default:
case 1:
return newUser;
case 2:
return access;
case 3:
return display;
}
}
int main()
{
logIn();
return 0;
}
i expected the function num to call newUser when 1 is passed, but exits instead with 0
what could be the problem? i also tried changing the parameter to char and string with the same result
If you return funcpointer you probably want to call it. You could make it by writing () after funcpointer object like this run(num)();

How to access private member - array with friend function

I am new to C++ and I write code to see how friend functions work. Here are two classes and I ask the user in friend function for parameters, which if they are equal with the values of the member variables, to be displayed. And I can't access one of the private members - the array with the country names. In the function int elcountry(element &e, supply s) I am trying to display the number of elements which are of a certain type and from a particular country. The error is that member supply::country, (s.country[i]) in elCountry function is inaccessible. I don't know how to use getCountry() function to access the private array.
class element {
friend class supply;
private:
string name;
double value;
int serial;
public:
element();
int elCountry(element &e, supply &s);
double* nominals(element &e, supply &s);
string getName() {
return name;
}
int getSerial() {
return serial;
}
};
class supply {
private:
int serial;
string country[5];
int n;
public:
supply();
string* getCountry() {
string country = new string[5];
return country;
}
friend int elCountry(element &e, supply &s);
friend double* nominals(element &e, supply &s);
};
int elcountry(element &e, supply s){
string names, Country;
int n;
cout << "enter country = "; cin >> Country;
cout << "enter name of the element = "; cin >> names;
cout << "enter number of elements = "; cin >> n;
for (int i = 0; i < 5; i++) {
if (Country == s.country[i] && names == e.getName() && n == e.getSerial()) {
cout << "the country is " << count << endl;
cout << "the name is" << names << endl;
cout << "the number is " << n << endl;
}
}
return n;
}
The signature of two functions don't match, they're irrelevant, it's not friend function at all.
friend int elCountry(element &e, supply &s);
~ ~
int elcountry(element &e, supply s){
~
Note that the names don't match either.

save and load c++ program

Ok so I figured out and learned a lot of stuff today and I want to thank the community for that. I haven't had any bump in the roads for a few hours now but now I'm stuck.
The last bump in the road. Saving and Loading my program. I have no idea where to start. I looked at how fwrite... and fread... works and all the examples are for programs that aren't split. I don't know where to start with my files. I'll put up 2 functions. If someone can help me how to do save those I can probably figure out the rest.
in gradebook.h
class Student {
public:
string last;
string first;
int student_id;
};
class Course {
public:
string name;
int course_id;
vector <Student> students;
};
class Gradebook {
public:
Gradebook();
void addCourse();
void addStudent();
private:
vector <Course> courses;
};
in gradebook.cpp
void Gradebook::addCourse() {
int i, loop=0;
cout << "Enter Number of Courses: ";
cin >> loop;
for(i=0; i<loop; i++) {
//create newEntry to store variables
Course newEntry;
cout << "Enter Course ID: ";
cin >> newEntry.course_id;
cout << "Enter Course Name: ";
cin >> newEntry.name;
//set variables from newEntry in Courses
courses.push_back(newEntry);
}
}
void Gradebook::addStudent() {
int i, loop=0;
cout << "Enter Number of Students: ";
cin >> loop;
for(i=0; i<loop; i++) {
//create newEntry to store variables
Student newEntry;
cout << "Enter Student ID: ";
cin >> newEntry.student_id;
cout << "Enter Last Name: ";
cin >> newEntry.last;
cout << "Enter First Name: ";
cin >> newEntry.first;
//set variables from newEntry in Students
courses[0].students.push_back(newEntry);
}
}
So if a user was to input some variables in courses and students how would i use fwrite... to save the data?
I wouldn't recommend fwrite, instead look into <fstream>. ifstream, ofstream
Basic saving:
ofstream out("data.txt"); //save file data.txt
out << thedata; //use the << operator to write data
Basic loading:
ifstream in("data.txt"); //reopen the same file
in >> thedata; //use the >> operator to read data.
Here's some sample code that might help without solving the whole thing for you.
#include<iostream>
#include<string>
#include<vector>
#include<fstream>
class Student {
public:
Student()
: student_id(0)
{
}
Student(const std::string &f, const std::string &l, int id)
: first(f)
, last(l)
, student_id(id)
{
}
std::string last;
std::string first;
int student_id;
};
std::ostream &operator <<(std::ostream &os, const Student &s)
{
os << s.last << '\t'
<< s.first << '\t'
<< s.student_id << '\t';
return os;
}
std::istream &operator >>(std::istream &is, Student &s)
{
is >> s.last
>> s.first
>> s.student_id;
return is;
}
bool WriteIt(const std::string &sFileName)
{
std::vector<Student> v;
v.push_back(Student("Andrew", "Bogut", 1231));
v.push_back(Student("Luc", "Longley", 1232));
v.push_back(Student("Andrew", "Gaze", 1233));
v.push_back(Student("Shane", "Heal", 1234));
v.push_back(Student("Chris", "Anstey", 1235));
v.push_back(Student("Mark", "Bradtke", 1236));
std::ofstream os(sFileName);
os << v.size();
for (auto s : v)
os << s;
return os.good();
}
bool ReadIt(const std::string &sFileName)
{
std::ifstream is(sFileName);
int nCount(0);
is >> nCount;
if (is.good())
{
std::vector<Student> v(nCount);
for (int i = 0; i < nCount && is.good(); ++i)
is >> v[i];
if (is.good())
for (auto s : v)
std::cout << s << std::endl;
}
return is.good();
}
int main()
{
const std::string sFileName("Test.dat");
return !(WriteIt(sFileName) && ReadIt(sFileName));
}
Bonus points if you recognise who my "students" are. :-)

Needing some help with two errors (C++)

Ive been up for a while coding and it is probably an easy mistake that im just overlooking from lack of sleep, but the problem happens with this segment of code.
do
{
aWithIntAcct.enterAccountData();
aWithIntAcct.getSavInfo();
aWithIntAcct.getCheckingInfo();
checkAcct.push_back(aWithIntAcct);
cout << "Would you like to enter another Checking Account with interest? y or n ";
cin >> quitChar;
}while(quitChar != QUIT);
it says that I have ambiguous access of 'enterAccountData' (Error C2385)
This is contradictory to the other (Error C3861) identifier not found.
My Classes are inherited so im not sure why this inst working for me. Any suggestions?
REST OF CODE:
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
template <class T>
void repeatValue(T val, int times)
{
for(int x = 0; x < times; x++)
{
cout << "-";
}
};
template <class T>
void produceReport(int tableRows, string title, T acctType)
{
cout << tableRows << endl;
cout << title << endl;
cout << acctType;
};
class BankAccount
{
friend ostream& operator<<(ostream&, const BankAccount&);
friend istream& operator>>(istream&, BankAccount&);
private:
int acctNum;
double acctBal;
public:
BankAccount(int = 0,double = 0.0);
double operator+=(BankAccount);
int operator+(BankAccount);
friend bool operator>(BankAccount &acctBalOne, BankAccount &acctBalTwo);
friend bool operator<(BankAccount &acctBalOne, BankAccount &acctBalTwo);
int operator==(const BankAccount acctNumOne);
void enterAccountData();
void displayAccount();
void setAcctNum(int);
void setAcctBal(double);
int getAcctNum();
double getAcctBal();
};
BankAccount::BankAccount(int num, double bal)
{
acctNum = num;
acctBal = bal;
}
double BankAccount::operator+=(BankAccount bankAcct)
{
acctBal += acctBal + bankAcct.acctBal;
return acctBal;
}
int BankAccount::operator+(BankAccount newAcctNum)
{
const int INCREMENT = 1;
newAcctNum.acctNum = acctNum + INCREMENT;
return newAcctNum.acctNum;
}
bool operator>(BankAccount &acctBalOne, BankAccount &acctBalTwo)
{
return acctBalOne.acctBal > acctBalTwo.acctBal;
}
bool operator<(BankAccount &acctBalOne, BankAccount &acctBalTwo)
{
return acctBalOne.acctBal < acctBalTwo.acctBal;
}
int BankAccount::operator== (const BankAccount acctNumOne)
{
int truth = 0;
if(acctNum == acctNumOne.acctNum)
truth = 1;
return truth;
}
ostream& operator<<(ostream& display, const BankAccount& aAcct)
{
display << "Account #" << aAcct.acctNum << endl;
display << "Account Balance $" << aAcct.acctBal << endl;
return display;
}
istream& operator>>(istream& dataIn, BankAccount& aAcct)
{
cout << endl << "Enter in an Account # ";
dataIn >> aAcct.acctNum;
cout << "Enter in an Account Balance $ ";
dataIn >> aAcct.acctBal;
return dataIn;
}
void BankAccount::enterAccountData()
{
cout << "Enter the Account:#";
cin >> acctNum;
cout << endl << "Enter the Account Balance:$";
cin >> acctBal;
}
void BankAccount::displayAccount()
{
cout << "The Account number is #" << acctNum << endl;
cout << "The Account Balance is $" << acctBal << endl;
}
void BankAccount::setAcctNum(int num)
{
acctNum = num;
}
void BankAccount::setAcctBal(double bal)
{
acctBal = bal;
}
int BankAccount::getAcctNum()
{
return acctNum;
}
double BankAccount::getAcctBal()
{
return acctBal;
}
class SavingsAccount : public BankAccount
{
friend ostream& operator<<(ostream&, const SavingsAccount&);
private:
double interest;
public:
SavingsAccount(double = 0.0);
void displaySavAccount();
void getSavInfo();
};
SavingsAccount::SavingsAccount(double intRate)
{
interest = intRate;
}
void SavingsAccount::getSavInfo()
{
cout << "Enter Interest Rate: ";
cin >> interest;
}
ostream& operator<<(ostream& display, SavingsAccount& aSavAcct)
{
aSavAcct.displaySavAccount();
return display;
}
void SavingsAccount::displaySavAccount()
{
cout << " Savings information. " << endl;
cout << "Interest Rate on the account is:" << interest << endl;
}
class CheckingAccount : public BankAccount
{
friend ostream& operator<<(ostream& display, const CheckingAccount& aCheckAcct);
private:
double monthlyFee;
int checksAllowed;
public:
CheckingAccount(double = 0,int = 0,int = 0,double = 0);
void displayCheckAccount();
void getCheckingInfo();
};
CheckingAccount::CheckingAccount(double fee, int allowed, int num, double bal) : BankAccount(num,bal), monthlyFee(fee), checksAllowed(allowed)
{
}
void CheckingAccount::getCheckingInfo()
{
cout << "Enter monthly fee of the Account for the checking account. $";
cin >> monthlyFee;
cout << endl << "How many checks are allowed?" << endl;
cin >> checksAllowed;
}
ostream& operator<<(ostream& display, CheckingAccount& aCheckAcct)
{
aCheckAcct.displayCheckAccount();
return display;
}
void CheckingAccount::displayCheckAccount()
{
cout << " Checking Information " << endl;
BankAccount::displayAccount();
cout << "Monthly fee on the account is:$" << monthlyFee << endl;
cout << "Checks allowed for this account is: " << checksAllowed << endl;
}
class CheckingWithInterest : public SavingsAccount, public CheckingAccount
{
private:
public:
CheckingWithInterest();
void displayWithInterest();
};
CheckingWithInterest::CheckingWithInterest() : CheckingAccount(0,0,9999,0), SavingsAccount(0.03)
{}
void CheckingWithInterest::displayWithInterest()
{
CheckingAccount::displayCheckAccount();
SavingsAccount::displaySavAccount();
}
int main()
{
cout << fixed << setprecision(2);
unsigned count;
vector<SavingsAccount>savAcct;
SavingsAccount aSavAcct;
vector<CheckingAccount>checkAcct;
CheckingAccount aCheckAcct;
vector<CheckingWithInterest>withIntAcct;
CheckingWithInterest aWithIntAcct;
const char QUIT = 'n';
char quitChar = 'y';
cout << "Do you want to enter Savings Information? y or n ";
cin >> quitChar;
do
{
aSavAcct.enterAccountData();
aSavAcct.getSavInfo();
savAcct.push_back(aSavAcct);
cout << "Would you like to enter another Savings Account? y or n ";
cin >> quitChar;
}while(quitChar != QUIT);
cout << "Do you want to enter Checking Information? y or n ";
cin >> quitChar;
do
{
aCheckAcct.enterAccountData();
aCheckAcct.getCheckingInfo();
checkAcct.push_back(aCheckAcct);
cout << "Would you like to enter another Checking Account? y or n ";
cin >> quitChar;
}while(quitChar != QUIT);
cout << "Do you want to enter Checking with interest account Information? y or n ";
cin >> quitChar;
do
{
aWithIntAcct.enterAccountData(); // error points here for both (Line 233)
aWithIntAcct.getSavInfo();
aWithIntAcct.getCheckingInfo();
checkAcct.push_back(aWithIntAcct);
cout << "Would you like to enter another Checking Account with interest? y or n ";
cin >> quitChar;
}while(quitChar != QUIT);
sort(savAcct.begin(), savAcct.end());
for(count = 0; count < savAcct.size(); ++count)
{
repeatValue(savAcct.at(count), count);
cout << endl;
produceReport(savAcct.size(), "Savings Account Information", savAcct.at(count));
}
sort(checkAcct.begin(), checkAcct.end());
for(count = 0; count < checkAcct.size(); ++count)
{
repeatValue(checkAcct.at(count), count);
cout << endl;
produceReport(checkAcct.size(), "Checking Account Information", checkAcct.at(count));
}
sort(withIntAcct.begin(), withIntAcct.end());
for(count = 0; count < withIntAcct.size(); ++count)
{
repeatValue(withIntAcct.at(count), count);
cout << endl;
produceReport(withIntAcct.size(), "Checking with interest Account Information", withIntAcct.at(count));
}
system("pause");
return 0;
}
class BankAccount
class SavingsAccount : public BankAccount
class CheckingAccount : public BankAccount
class CheckingWithInterest : public SavingsAccount, public CheckingAccount
This inheritance hierarchy is (probably) incorrect. Right now it looks like this:
BankAccount BankAccount
| |
SavingsAccount CheckingAccount
\ /
CheckingWithInterest
So, each CheckingWithInterest object actually has two BankAccount base class subobjects: one from its SavingsAccount base class subobject and one from its CheckingAccount base class subobject.
So, when you try to call a BankAccount member function on a CheckingWithInterest object, e.g.,
CheckingWithInterest account;
account.enterAccountData();
the compiler doesn't know whether you mean the enterAccountData() from the BankAccount that is part of the SavingsAccount base class or you mean the enterAccountData() from the BankAccount that is part of the CheckingAccount base class.
I'm not sure what, exactly, your requirements are, but if you only want to have a single BankAccount base class subobject, you probably need to use virtual inheritance when you derive CheckingAccount and SavingsAccount from BankAccount, so that the BankAccount subobject is shared between them when they are composed in CheckingWithInterest:
class BankAccount
class SavingsAccount : public virtual BankAccount
class CheckingAccount : public virtual BankAccount
class CheckingWithInterest : public SavingsAccount, public CheckingAccount
If you really do want there to be two BankAccount base class subobjects, then when you call enterAccountData(), you need to qualify on which base class subobject you want to call the member function:
account.CheckingAccount::enterAccountData();