How to Create multiple classes in C++? - c++

Create 200 classes (think about an efficient way to do this), each class will contain the following public members:
a. Name - Which will hold first and last name
b. Address- which will hold the street number and name
c. Phone - which will hold the phone number
The user will be able to enter the information for between 1 and 200 individuals(determined by the user).
#include<iostream>
#include<string>
using namespace std;
class information {
public:
//member variables go here
};
int main() {
char answer = 'Y';
int i = 0; //why is this here?
//instantiate your classes here
do {
cout << "This is the address book enter the first and last name "
<< "address and phone number: \n";
cout << "Name (First and Last): ";
//will need a 'cin' to store the name (hint: use getline)
cout << "\n\nAddress: ";
//address
cout << "\n\nPhone Number: ";
//phone
i++;
cout << "Enter another person? Y/N: ";
//answer Y or N
} while ;
system("pause");
return 0;
}

class information {
public:
//member variables go here
string name, address,phone;
};
And in the main method, write
information info[200];
This creates 200 objects of class information. To set values, you need to run a loop like:
for(i=0;i<200;i++)
{
cin>>info[i].name>>info[i].address>>info[i].phone;
}

Related

C++: Program crashes when I try to access a private class string variable. Why is this, and what can I do to fix it?

I am writing a bank account program that provides a menu system for the user, which allows them to choose between 4 options: A) Add a customer, B) Print all customer data, C) Update customer data, and D) Exit program. Each option performs separate tasks. The option I am focused on for this question is Option A.
Option A is supposed to generate a new bank account object and ask the user to input the account holder name, the initial deposit for the account (how much money to start with for the new account), and the interest rate. It then needs to set these values to the correct private values in the bankAccount class for any given object.
Code for main.cpp before Option B (there is a little more code after this, hence the lack of backward brackets at the end, but I want to try and keep this more concise):
#include <iostream>
#include <string>
#include <cstdlib>
#include "header.h"
#include "implementation.cpp"
using namespace std;
int main()
{
//array of bankAccount class objects (up to 20)
bankAccount account[20];
string menuInput = ""; //used for menu loop input
string accNameInput = ""; //used for account customer name user input
float depositInput = 0; //used for initial deposit input
float interestInput = 0; //used for initial interest input
// int customerCount = 0; //used to compare to static int to determine # of customers in memory
int static i = 0;
//while loop keeps user in the menu until they choose to exit program
while (true)
{
cout << endl << "Enter a letter option below: "
<< endl << endl << "A: Add a customer" << endl << "B: Print all customer data available"
<< endl << "C: Update customer data" << endl << "D: End program" << endl << endl;
cin >> menuInput;
//Option A: Add a customer
if (menuInput == "A" || menuInput == "a")
{
//checking for max customer limit
if (i > 19)
{
cout << endl << "Cannot add customer; Max customer capacity reached." << endl;
}
else //
{
///Creates a new customer account and asks for new customer name,
///initial deposit amount, & interest
cout << endl << "Bank account #" << (i + 1) << " created." << endl;
bankAccount account[i]; //new bank account object created
//time to set the name for our new customer...
cout << endl << "Enter customer name for account #" << (i + 1) << ": " << endl;
cin >> accNameInput;
//setting initial deposit amount
cout << endl << "Enter initial deposit amount for account #" << (i + 1) << ": " << endl;
cin >> depositInput;
//setting initial interest rate
cout << endl << "Enter interest rate (without % sign): " << endl;
cin >> interestInput;
account[i].setInterestRate(interestInput);
account[i].setBalance(depositInput);
account[i].setAccountHolderName(accNameInput);
//increments the account number counter
i++;
}
}
The problem persists with setAccountHolderName() found on the last line here:
account[i].setInterestRate(interestInput);
account[i].setBalance(depositInput);
account[i].setAccountHolderName(accNameInput);
When I call the class functions setInterestRate and setBalance to set the input values to their respective private class variables, the program proceeds like normal and takes the user back to the main menu as it should. But calling setAccountHolderName crashes the program and returns this value: -1073741819 (0xC0000005).
I'll include some code from the header and implementation files below to show how I have accountHolderName code programmed in:
header.h (includes accountHolderName get/set functions):
///Name of file: header.h
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#include <iostream>
#include <string>
using namespace std;
class bankAccount
{
//private data values
string accountHolderName;
int accountNumber;
//static int accCounter; //keeps track of account numbers
float balance;
float interestRate;
public:
//Default constructor
bankAccount();
///Getters/setters for all private member variables
//accountNumber
int getAccountNumber();
void setAccountNumber(int accNum);
//accountHolderName
string getAccountHolderName();
void setAccountHolderName(string accName);
implementation.cpp (includes accountHolderName implementation):
///Name of file: implementation.cpp
#include <iostream>
#include <string>
#include "header.h"
using namespace std;
//static int definition (guess you have to define static members here?)
//int bankAccount::accCounter;
//Default constructor
bankAccount::bankAccount()
{
accountHolderName = "";
accountNumber = 0;
// accCounter = 0;
balance = 0;
interestRate = 0;
}
///Getters/setters for all private member variables
//accountNumber
int bankAccount::getAccountNumber()
{
return accountNumber;
}
void bankAccount::setAccountNumber(int accNum)
{
accountNumber = accNum;
}
//accountHolderName
string bankAccount::getAccountHolderName()
{
return accountHolderName;
}
void bankAccount::setAccountHolderName(string accName)
{
accountHolderName = accName;
}
It seems like messing with the code in certain ways (such as completely deleting the code that comes after Option A's code, commenting out accountHolderName = ""; in the default constructor, etc.) will temporarily allow account[i].setAccountHolderName(accNameInput); to function without crashing the program, but this is incredibly inconsistent and confuses me even more. I'm not sure if the issue has to do with memory or what. I have also tried using cout to see if the input variable accNameInput from main.cpp is getting stored to, which it is.
Sorry if this is simply too much code or explaining; this is my first post and I just wanted to provide a good chunk of my code so you could see the full scale of things. All I am trying to do here is access the bankAccount class private string variable, accountHolderName, and store user input into each new object.
I tried troubleshooting this issue online but couldn't seem to find anything that had a similar issue. I'm not sure what I'm missing; any help or guidance would be incredibly appreciated.
Technically, this line:
bankAccount account[i]; //new bank account object created
Isn't allowed in C++, but some compilers (g++) allow it as an extension since they do formally support variable stack arrays with the C compiler.
Further, that declaration overrides the variable of the same name declared at a higher scope
But then you get to these lines:
account[i].setInterestRate(interestInput);
account[i].setBalance(depositInput);
account[i].setAccountHolderName(accNameInput);
But valid indices of an array range for 0..i-1 So you're already in undefined behavior with your array index out of bounds.
I suspect you really meant this:
bankAccount newAccount; //new bank account object created
...
newAccount.setInterestRate(interestInput);
newAccount.setBalance(depositInput);
newAccount.setAccountHolderName(accNameInput);
account[i] = newAccount;
i++;

Is there a way to access a class object's information based on a user's input?

hope this hasn't been answered before, looked around and couldn't find it. Was wondering how to to access a specific class object based on a users input. Sort of in a similar way that you would access the value of a specific index of an array based on the user's input and going to that index.
I'm not entirely sure what I would do seeing as there isn't an accessible integer like there is in an array. Relatively new to programming so sorry if something I have said doesn't make sense.
class Hams {
public:
string name;
};
int main()
{
int userNum;
Hams ham1;
ham1.name = "Porky";
Hams ham2;
ham2.name = "Wilbur";
Hams ham3;
ham3.name = "Piglet";
cout << "Enter num of pig you want to know the name of: ";
cin >> userNum;
//Output the correct name
}
If the user enters in 3, then the output should be "Piglet".
cout << ham(userNum).name << endl;
I know this code isn't correct but its how I can best express what I'm trying to do.
Is there a way to do this or something similar to it other than an if statement like below?
if (userNum == 3) {
print(ham3.name);
}
This is one way of doing it:
std::array<std::string, 3> pigs = {"Porky", "Wilbur", "Piglet"};
int userNum;
std::cout << "Enter num of pig you want to know the name of: ";
std::cin >> userNum;
std::cout << pigs[userNum-1] << std::endl;
EDIT* To be more exact to your use case, here is another example:
class Hams {
public:
std::string name;
};
int main()
{
std::array<Hams, 3> pigs = {"Porky", "Wilbur", "Piglet"};
int userNum;
std::cout << "Enter num of pig you want to know the name of: ";
std::cin >> userNum;
std::cout << pigs[userNum-1].name << std::endl;
}

How to relay cin from main into fucntions and struct above main?

ok so i need to figure out how to place the cin user entered in main into the function, and then from the function into the struct; im clueless on what i need to do in the main not just regarding the code but how it connects (memory wise) what is written into the main with the rest of the program. the #include must be ONLY iostream, vector ANDstring!
p.s at the end i need to print out the films stored in the vector of films
using namespace std;
struct Film
{
string Name;
double Length;
string Producer;
string Lead_Role;
string Type;
};
Film create_film()
{
Film f;
cout << "Enter the name of the movie: ";
getline(cin, f.Name);
cout << "Enter movie length: ";
cin >> f.Length;
cin.ignore;
cout << "Enter the producer: : ";
getline(cin, f.Producer);
cout << "Enter the lead role: ";
getline(cin, f.Lead_Role);
cout << "Enter movie type";
getline(cin, f.Type);
return f;
}
int main()
{
//here i need to figure it out
return 0;
}
I think (it's not completely clear) that you're just looking for
int main()
{
Film my_film = create_film();
// do something with my_film
...
return 0;
}
The way I've used create_file() in main is called a function call. It's how you 'connect' one function to another, though 'transfer control' is probably a better way of saying it. When you call a function control transfers from the calling function (main in this case) to the called function (create_film in this case). When the called function returns control goes back to the calling function. And of course when the main function returns the program terminates.

Inputing strings in c++ using class is not working properly

#include<fstream>
#include<iostream>
using namespace std;
class employee
{
char *name;
int age;
string designation; // string data type is used
float salary;
public:
void getdata();
void display();
};
void employee::getdata() // for taking the input
{
cout<<"\nENTER THE NAME OF THE EMPLOYEE: ";
gets(name); /*name is a char pointer */
cout<<"\nENTER THE AGE OF THE EMPLOYEE: ";
cin>>age;
cout<<"\nENTER THE DESIGNATION OF THE EMPLOYEE: ";
getline(cin,designation); /*designation is string data type*/
cout<<"\nENTER THE SALARY OF THE EMPLOYEE: ";
cin>>salary;
}
void employee::display()//for displaying the inputed data
{
cout<<"\nTHE NAME OF THE EMPLOYEE: ";
puts(name);
cout<<"\nENTER THE AGE OF THE EMPLOYEE: ";
cout<<age;
cout<<"\nENTER THE DESIGNATION OF THE EMPLOYEE: ";
cout<<designation;
cout<<"ENTER THE SALARY OF THE EMPLOYEE: ";
cout<<salary;
}
int main()
{
ofstream fout;
char ch;
fout.open("employee.txt",ios::out|ios::binary);/*use of open function in file handing*/
employee e;
for(int i=0;i<3;i++)
{
e.getdata();
fout.write((char*)&e,sizeof(e));//write() is used
}
fout.close();
ifstream fin;
fin.open("employee.txt",ios::in|ios::binary);
int j;
cout<<"\n Enter the employee no. to be read ";
cin>>j;
fin.seekg((j-1)*sizeof(e));
fin.read((char*)&e,sizeof(e));
cout<<"\n Details of employee no. of object is = ";
e.display();
return 0;
}
I am not able to identify the error in my code...I had cross checked the code...there is no syntax error and no compiler error but the output is not correct...it is not taking the proper input from the user.
As Bo Persson said, your program does not provide any memory for name and designation. You declare pointers like name in your class alright, but they do not point to anything. You could just declare e.g. name as char name[100]; and hope that 100 is enough (and, in production code, add checks to ensure it isn't exceeded).
But in C++ there is the string class which frees you of many worries. In particular, it makes input of arbitrarily long strings easy. If the string can't have whitespace in it, a simple string s; cin >> s; reads a "word" from the input into the string. If it can have whitespace, you need some way to tell where it starts and ends. Databases, Excel etc. often use quotes to surround a string. If it cannot contain newlines, ensuring that it is on a line of its own is sufficient and obviates the need for parsing. That's what we'll do here.
The second issue you faced is what's technically called "serialization". You want to store ("persist") your class on disk and later (much later, perhaps) re-read it into a new instance. Nathan Oliver pointed you to a resource which discusses serialization. For a simple class like employee with a limited number of simple data members we can simply roll our own ad-hoc serialization: We write everything to disk with operator<<(), and read everything back with operator>>().
The main thing to consider is that strings may have whitespace, so that we'll put them on a line of their own.
An addition is that in order to be more robust when reading from a file we start each employee with a start marker (header in the code below). This way reading an employee will work from any position in the file. Also, if later employees should have more fields we can still read our basic employee data and just skip the additional fields before we read the next employee in a sequence of employees on disk.
streams are closed automatically when they are destroyed at the end of their scope; we use block scope for that (check the additional {} in the code).
A plain float is not precise enough for higher salaries (it only has about 7 decimal digits, so that for salaries > 167772.16 (if I can believe Wikipedia) in whatever currency the pennies start to fall off the cliff). I use long double and make sure to not lose precision when converting it to text.
You didn't compare reals but I did in order to check whether I read the employee back correctly. Care must be taken there. I wiggle out of the gory details by comparing half pennies which should be appropriate for money.
Here is the whole program. (Compared with my previous version I have simplified the (de)serialization, in particular I have eliminated the useless tags.)
It would be wise to perform error checking after each read/write in order to make sure it succeeded; remember, a stream coverts to bool, so a simple if(!os) { cerr << "oops" << endl; /* exit? */} is enough; but I didn't want to distract from the actual program too much.
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <cfloat> // for LDBL_DIG in ostream precision.
#include <cstdlib> // for exit()
using namespace std;
/** A simple class holding employee information */
class employee
{
public:
/** This header starts each
"serialization" of an employee on a line
of its own. */
static constexpr const char *header = "--- Employee ---";
// use C++ std::string
string name;
int age;
// use C++ std::string
string designation;
// Be as precise as possible,
// for later uses like salary increases
// by 4.5% or so :-)
// The salary is in units like USD or EUR.
// The fraction part is pennies, and fractions of them.
long double salary;
public:
void readdata(istream &is);
void writedata(ostream &os);
void display();
bool operator==(employee &rhs)
{ return
name == rhs.name
&& age == rhs.age
&& designation == rhs.designation
// Do not compare floats directly.
// We compare pannies, leaving slack for rounding.
// If two salaries round to the same penny value,
// i.e. 0.01, they are equal for us.
// (This may not be correct, for an accounting app,
// but will do here.)
&& salary - rhs.salary < 0.005
&& rhs.salary - salary < 0.005;
}
};
/** Write a header and then
each data member in declaration order, converted to text,
to the given stream. The header is used to find the start
of the next employee; that way we can have comments or other
information in the file between employees.
The conversion is left to operator<<.
Each member is written to a line of its own, so that we
can store whitespace in them if applicable.
The result is intended to be readable by #readdata().
*/
void employee::writedata(ostream &os)
{
os.precision(LDBL_DIG); // do not round the long double when printing
// make sure to start on a new line....
os << endl
// ... write the header on a single line ...
<< header << endl
// ... and then the data members.
<< name << endl
<< age << endl
<< designation << endl
<< salary << endl;
}
/**
Read an amployee back which was written with #writedata().
We first skip lines until we hit a header line,
because that's how an employee record starts.
Then we read normal data mambers with operator>>.
(Strictly spoken, they do not have to be on lines
of thier own.)
Strings are always on a line of their own,
so we remove a newline first.
*/
void employee::readdata(istream &is)
{
string buf;
while(getline(is, buf)) // stream converts to bool; true is "ok"
{
if( buf == header) break; // wait for start of employee
}
if( buf != header )
{
cerr << "Error: Didn't find employee" << endl;
return;
}
getline(is, name); // eats newline, too
is >> age; // does not eat newline:
// therefore skip all up to and including the next newline
is.ignore(1000, '\n');
// line on its own, skips newline
getline(is, designation);
is >> salary;
}
int main()
{
const char *const fname = "emp.txt";
employee empa;
empa.name = "Peter A. Schneider";
empa.age = 42;
empa.designation = "Bicycle Repair Man";
empa.salary = 12345.67;
employee empb;
empb.name = "Peter B. Schneider";
empb.age = 43;
empb.designation = "Bicycle Repair Woman";
empb.salary = 123456.78;
{
ofstream os(fname);
if(!os)
{
cerr << "Couldn't open "
<< fname << " for writing, aborting" << endl;
exit(1);
}
empa.writedata(os);
cout << "Employee dump:" << endl;
empa.writedata(cout);
// insert a few funny non-employee lines
os << endl << "djasdlköjsdj" << endl << endl;
empb.writedata(os);
cout << "Employee dump:" << endl;
empb.writedata(cout);
}
// show the file contents
{
ifstream is(fname);
if(!is)
{
cerr << "Couldn't open "
<< fname << " for reading, aborting" << endl;
exit(1);
}
string line;
cout << "-------------- File: -------------" << endl;
while(getline(is, line)) cout << line << endl;
cout << "---------------End file ----------" << endl;
}
/////////////////////////////////////////////////////////
{
ifstream is(fname); // read from the file "emp.txt" just written
if(!is)
{
cerr << "Couldn't open "
<< fname << " for reading, aborting" << endl;
exit(1);
}
{
employee emp2; // new employee, sure to be empty
cout << endl << "Re-reading an employee..." << endl;
emp2.readdata(is);
cout << endl << "Re-read employee dump:" << endl;
emp2.writedata(cout);
cout << "Original and written/read employee are "
<< (empa == emp2 ? "" : "NOT ") << "equal" << endl;
}
{
employee emp2; // new employee, sure to be empty
// now read next employee from same stream.
// readdata() should skip garbage until the header is found.
cout << endl << "Re-reading an employee..." << endl;
emp2.readdata(is);
cout << endl << "Re-read employee dump:" << endl;
emp2.writedata(cout);
cout << "Original and written/read employee are "
<< (empb == emp2 ? "" : "NOT ") << "equal" << endl;
}
}
}
Sample session:
Employee dump:
--- Employee ---
Peter A. Schneider
42
Bicycle Repair Man
12345.6700000000001
Employee dump:
--- Employee ---
Peter B. Schneider
43
Bicycle Repair Woman
123456.779999999999
-------------- File: -------------
--- Employee ---
Peter A. Schneider
42
Bicycle Repair Man
12345.6700000000001
djasdlköjsdj
--- Employee ---
Peter B. Schneider
43
Bicycle Repair Woman
123456.779999999999
---------------End file ----------
Re-reading an employee...
Re-read employee dump:
--- Employee ---
Peter A. Schneider
42
Bicycle Repair Man
12345.6700000000001
Original and written/read employee are equal
Re-reading an employee...
Re-read employee dump:
--- Employee ---
Peter B. Schneider
43
Bicycle Repair Woman
123456.779999999999
Original and written/read employee are equal
In addition to what the comments say about gets being dangerous, you immediately run into that buffer overflow by not allocating any space for name. Just having a pointer is not enough.
In addition to that, mixing cin >> and getline(cin,...) is known to skip input, because the two functions handle end-of-line differently.
Then we have the problem of doing binary I/O for the employee type. In general, you cannot do that for class types that are non-trivial. Specifically, the std::string designation member internally holds a pointer to some data. That pointer will not survive the transfer to disk and back.

How to display the name from the array name?

I'm trying to study c++ about array
and I'm having a problem displaying the name from the array name
Because when I try to display the name of the passenger based on where he seat
the first letter becomes the last letter of his name..ahmm
Here's my code
#include <iostream.h>
#include <conio.h>
char* name[10]={" "};
int* seat=0;
char* pname="The Passenger is: ";
char ask;
void display();
int main()
{
clrscr();
cout<<"The Entering of name and seat number..."<<endl;
do
{
cout<<"\nEnter your name: ";
cin>>*name;
cout<<"Enter your seat number: ";
cin>>*seat;
cout<<"Do you want to input again?(Y/N): ";
cin>>ask;
}
while(ask=='y'||ask=='Y');
cout<<"\nDo you want to see the passenger's name?(Y/N): ";
cin>>ask;
if(ask=='y'||ask=='Y')
{
cout<<"\nThe Program will now direct you to the displaying of passenger's name...."<<endl;
display();
}
else
{
cout<<"\n\nThe Program will end shortly....";
}
getch();
return 0;
}
void display()
{
do
{
cout<<"\nEnter seat number to display passenger's name: ";
cin>>*seat;
cout<<pname<<*name[*seat-1]<<endl;
cout<<"Do you want to try again?(Y/N): ";
cin>>ask;
}
while(ask=='y'||ask=='Y');
cout<<"\nThe Program will now end shortly....";
getch();
}
To display the name from the array name you have at first to define the array correctly.:)
If you do not know yet about standard class std::string then the array should be defined as for example
char name[10][20];
that is it can store 10 names that have length no more than 20 characters.
Or if you know about class std:string then you can define it as
#include <string>
std::string name[10];
And it would be even better to define
#include <string>
#include <array>
std::array<std::string, 10> name;
For this program neither pointer is needed to be defined.
Take into account that when you ask to enter a seat number you should check that this number is in the range 1 - 10 (in this case you will need to decrease it by one when will use it to access the array) or 0 - 9.
You seem to be having a problem with pointers. Namely
int* seat=0;
will not allocate space for the integer, but instead allocate space for a pointer and then set this pointer and set it to address 0. When you perform
cin>>*seat;
Your program attempts to dereference the pointer which does not point to anything. Furthermore when you perform
cin >>*name
You are not writing to the whole string but instead writing to the dereference location, namely the first character of the string.
For a start change
int* seat=0;
to
int seat = 0
and
cin>>*name;
to
cin>>name;
good luck!
Edit:
also you want to change the:
cin >> *seat;
to
cin >> seat
Nevertheless you might need some more practice in the basic language features, like pointers, you could use some existing data structures. Since you are using cout and cin i assume your compiler supports the C++ standard library. I would use a map, to save the passengers.
#include <iostream>
#include <map>
struct passenger
{
char name[10];
};
std::map<int, passenger> passengers;
int seat;
char ask;
void display();
int main()
{
std::cout<< "The Entering of name and seat number..." << std::endl;
do
{
passenger p;
std::cout << "\nEnter your name: ";
std::cin >> p.name;
std::cout << "Enter your seat number: ";
std::cin >> seat;
// add passenger to the map
passengers.insert(std::pair<int, passenger>(seat, p));
std::cout << "Do you want to input again?(Y/N): ";
std::cin >> ask;
}
while(ask=='y'||ask=='Y');
std::cout << "\nDo you want to see the passenger's name?(Y/N): ";
std::cin >> ask;
if(ask=='y' || ask=='Y')
{
std::cout << "\nThe Program will now direct you to the displaying of passenger's name...." << std::endl;
display();
}
return 0;
}
void display()
{
do
{
std::cout << "\nEnter seat number to display passenger's name: ";
std::cin >> seat;
// check if passenger data is available for this seat
if(passengers.find(seat) != passengers.end()) {
std::cout << "The Passenger is: " << passengers[seat].name << std::endl;
} else {
std::cout << "Seat still available ..." << std::endl;
}
std::cout << "Do you want to try again?(Y/N): ";
std::cin >> ask;
}
while(ask=='y' || ask=='Y');
}
If you are using a pointer *seat you don't have to access it as
cin>>*seat. You only need to write cin>>seat.
While you are learning cpp, check out what pointers are too.
Here's a little info on that too, though that is not exactly the subject matter,
int *S; // pointer of type int
int x; // variable of type int
S = &x; // pointer S is now pointing to memory location of x
S = 4;
OR
x = 4; // changes the contents of memory location to which S points`
cout << *S; // displays the memory address to which S points i.e.
x