Input Element Causing Errors - class

My class is currently studying Classes and I'm attempting to complete my assignment due tomorrow. I have most of it done, however, for some reason the address input won't let me input any letters only numbers.
I can't figure out what I'm doing wrong here and would appreciate help in figuring out if I need to change something.
#include <iostream>
using namespace std;
class personalData
{
private:
string name;
string address;
int age;
string phNumber;
public:
void setName()
{
cout << "Enter name: ";
cin >> name;
}
string getName()
{
return name;
}
void setAddress()
{
cout << "Enter address: ";
cin >> address;
}
string getAddress()
{
return address;
}
void setAge()
{
cout << "Enter age: ";
cin >> age;
}
int getAge()
{
return age;
}
void setPhone()
{
cout << "Enter phone number: ";
cin >> phNumber;
}
string getPhone()
{
return phNumber;
}
void displayData()
{
cout << "\nName: " << getName() << endl;
cout << "Address " << getAddress() << endl;
cout << "Age: " << getAge() << endl;
cout << "Phone: " << getPhone() << endl;
}
};
int main()
{
personalData person1;
personalData person3;
personalData person2;
person1.setName();
person1.setAddress();
person1.setAge();
person1.setPhone();
person1.getAddress();
cout << "\n";
person2.setName();
person2.setAddress();
person2.setAge();
person2.setPhone();
person2.getAddress();
cout << "\n";
person3.setName();
person3.setAddress();
person3.setAge();
person3.setPhone();
person3.getAddress();
cout << "\n";
cout << "Person1 details: ";
person1.displayData();
cout << "Person2 details: ";
person2.displayData();
cout << "Person3 details: ";
person3.displayData();
return 0;
}
Here is what it looks like if you input both numbers and letters:
And here is what happens if you only input numbers:

Related

I can't find where std::option comes useful

I found above code in this link and it tells that this example where std::option nicely fits!
class UserRecord
{
public:
UserRecord(const std::string& name, std::optional<std::string> nick, std::optional<int> age)
: mName{ name }, mNick{ nick }, mAge{ age }
{
}
friend std::ostream& operator << (std::ostream& stream, const UserRecord& user);
private:
std::string mName;
std::optional<std::string> mNick;
std::optional<int> mAge;
};
std::ostream& operator << (std::ostream& os, const UserRecord& user)
{
os << user.mName << ' ';
if (user.mNick) {
os << *user.mNick << ' ';
}
if (user.mAge)
os << "age of " << *user.mAge;
return os;
}
int main()
{
UserRecord tim{ "Tim", "SuperTim", 16 };
UserRecord nano{ "Nathan", std::nullopt, std::nullopt };
std::cout << tim << "\n";
std::cout << nano << "\n";
}
I created another one without optional which is below and i find it more easier than one which uses std::option.
I think the second version is more readable because no need to use std::nullopt
class UserRecord
{
public:
UserRecord(const std::string& name, std::string nick = "", int age = 0)
: mName{ name }, mNick{ nick }, mAge{ age }
{
}
friend std::ostream& operator << (std::ostream& stream, const UserRecord& user);
private:
std::string mName;
std::string mNick;
int mAge;
};
std::ostream& operator << (std::ostream& os, const UserRecord& user)
{
os << user.mName << ' ';
if (user.mNick != "") {
os << user.mNick << ' ';
}
if (user.mAge != 0)
os << "age of " << user.mAge;
return os;
}
int main()
{
UserRecord tim{ "Tim", "SuperTim", 16 };
UserRecord nano{ "Nathan" };
std::cout << tim << "\n";
std::cout << nano << "\n";
}
So, why do we need to use optional in general and specially in this case?

Vector printing incorrect data

Can someone tell my why my program prints wrong values?
I've mostly followed an youtube video how to use vectors. And the program which was written, i was able to run it. I tried to implement the same method for my program which is for cars (video was for students). But i'm having problems. Funny part is, that the student program ran well, i don't remember changing anything to it, and now it also doesn't print anything at all.
So i'm trying to make a program that inputs car brand, year and price into a vector of a class and then print out all the stored information. But i'm currently getting mixed results.
I'm either getting blank spaces for results or some huge numbers and blank space for the brand (string)
When i'm not using references & i get blank results, with & i get what i've written below.
Does anyone have an idea?
When i input:
brand - Lambo
year - 1997
price 25000
I get:
Car brand:
Car year: 2686588
Car price: 6.95144e-308
main.cpp
#include <iostream>
#include <string>
#include "Car.h"
#include <vector>
using namespace std;
Car::Car(){
}
Car::Car(string brand, int year, double price){
brand;
year;
price;
}
Car::~Car(){
}
string Car::getBrand() const{
return brand;
}
int Car::getYear() const{
return year;
}
double Car::getPrice()const{
return price;
}
void Car::setBrand(string brand){
brand;
}
void Car::setYear(int year){
year;
}
void Car::setPrice(double price){
price;
}
void enterData(vector<Car>&);
void showData(const vector<Car>&);
int main(){
vector<Car> myGarage;
int chc;
cout << "-- M A I N M E N U --\n\n";
do{
cout << "Please make a choice\n\n";
cout << "1. Enter car details" << endl;
cout << "2. Show car details" << endl;
cout << "3. Exit" << endl;
cin >> chc;
switch(chc){
case 1:
enterData(myGarage);
break;
case 2:
showData(myGarage);
break;
case 3:
cout << "Have a nice day!";
break;
}
}
while(chc != 3);
}
void enterData(vector<Car>& newMyGarage){
string brand;
int year;
double price;
cout << "How many cars are in your garage?";
int garageSize;
cin >> garageSize;
for(int i = 0; i < garageSize; i++){
cout << "Car brand: ";
cin >> brand;
cout << "Car year: ";
cin >> year;
cout << "Car price: ";
cin >> price;
Car newCar(brand, year, price);
newMyGarage.push_back(newCar);
cout << endl;
}
}
void showData(const vector<Car>& newMyGarage){
unsigned int size = newMyGarage.size();
for(unsigned int s = 0; s < size; s++){
cout << "Car brand: " << newMyGarage[s].getBrand() << endl;
cout << "Car year: " << newMyGarage[s].getYear() << endl;
cout << "Car price: " << newMyGarage[s].getPrice() << endl;
cout << endl;
}
}
header file Car.h
#ifndef CAR_H_INCLUDED
#define CAR_H_INCLUDED
#include <iostream>
#include <string>
using namespace std;
class Car{
public:
string brand;
int year;
double price;
Car();
Car(string, int, double);
~Car();
string getBrand() const;
int getYear() const;
double getPrice() const;
void setBrand(string);
void setYear(int);
void setPrice(double);
};
#endif // CAR_H_INCLUDED

Template class method error "no 'void Pair<T1, T2>::display()' member function Pair declared in class"

I'm not sure if my syntax is incorrect. I am getting "no 'void Pair T1, T2::display()' member function Pair declared in class" as well as "no matching function for call to ‘Pair std::basic_string char, std::char_traits char" Here is the header file:
#ifndef PAIR_H
#define PAIR_H
#include <iostream>
#include <string>
using namespace std;
template <typename T1, typename T2 >
class Pair
{
private:
T1 t1;
T2 t2;
public:
Pair(const T1 & t1,const T2 & t2) : t1(t1), t2(t2) {};
T1 getFirst() const { return t1; };
T2 getSecond() const { return t2; };
//setters
void setFirst(const T1 & value) { t1 = value; };
void setSecond(const T2 & value) { t2 = value; };
};
template <typename T1, typename T2>
void Pair<T1,T2> :: display()
{
cout << t1 << " - " << t2 << endl;
}
#endif // PAIR_H
and this is the driver file.
#include <iostream>
#include <string>
using namespace std;
#include "pair.h"
int main()
{
string first;
cout << "Please enter a first name: ";
cin >> first;
string last;
cout << "Please enter a last name: ";
cin >> last;
Pair<string, string> fullName;
fullName.setFirst(first);
fullName.setSecond(last);
cout << "The first name is: " << fullName.getFirst() << endl;
cout << "The last name is: " << fullName.getSecond() << endl;
cout << "The complete pair is: ";
fullName.display();
cout << endl << endl;
int num1;
cout << "Please enter a number: ";
cin >> num1;
int num2;
cout << "Please enter another number: ";
cin >> num2;
Pair<int, int> numbers;
numbers.setFirst(num1);
numbers.setSecond(num2);
cout << "The first number is: " << numbers.getFirst() << endl;
cout << "The second number is: " << numbers.getSecond() << endl;
cout << "The complete pair is: ";
numbers.display();
cout << endl << endl;
string name;
cout << "Please enter a name: ";
cin >> name;
int score;
cout << "Please enter a score: ";
cin >> score;
Pair<string, int> grade;
grade.setFirst(name);
grade.setSecond(score);
cout << "The name is: " << grade.getFirst() << endl;
cout << "The score is: " << grade.getSecond() << endl;
cout << "The complete pair is: ";
grade.display();
cout << endl << endl;
return 0;
}
Yes, your syntax is incorrect.
1) display() is a member of Pair, so you must declare it inside the class.
You can add this declaration line in the public section
void display ();
or you can define display() inside the class (deleting the definition outside) [I added the const modifier]
void display () const { cout << t1 << " - " << t2 << endl; }
1 bis)
I suggest you to define the operator<< (output operator) for class Pair; something like, inside public, this
friend ostream & operator<< (ostream & os, Pair const & p)
{ return os << '(' << p.t1 << ',' << p.t2 << ')'; }
so you can simply output a pair like this
cout << fullName << endl;
2) You don't define a default constructor (without arguments), so you should define you pairs in this way
Pair<string, string> fullName("", "");
Pair<int, int> numbers(0, 0);
Pair<string, int> grade("", 0);
or, avoiding the following setFirst() and setSecond()
Pair<string, string> fullName(first , last);
Pair<int, int> numbers(num1, num2);
Pair<string, int> grade(name, score);
3) I don't know if you know it but there is a standard std::pair class (#include <utility>).
4) You should use che c++ tag for a question like this
5) Sorry for my bad English

Function Pointers in C++ Class Files

I've been trying to work with function pointers for quite a bit now, and to no avail. I've been working with a few friends to create a C++ 11 library to make creating ASCII games easier, and I've personally been working on creating a menu class. The beef of the class is complete, but one issue - I can't get the buttons to call functions. I always get the error:
terminate called after throwing an instance of 'std::bad_function_call'
what(): bad_function_call
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Obviously the error lies somewhere in the pointers, but I can't solve it for the life of me. Thanks for the help in advance.
Menu.h
#ifndef MENU_H
#define MENU_H
using namespace std;
#include <functional>
#include <string>
#include <map>
class Menu {
public:
int numberOfOptions;
map<int, string> options;
int currentSelection;
string title;
Menu();
Menu(int initialNumberOfOptions, map<int, string> initialOptions, int initialSelection);
void display();
void waitForInput();
void attachOptionAction(int option, void (*function)());
private:
map<int, void (*std::function<void()>)> optionActions;
void executeOptionAction(int option);
};
#endif
Menu.cpp
#include "Menu.h"
#include <windows.h>
#include <iostream>
#include <conio.h>
Menu::Menu(int initialNumberOfOptions, map<int, string> initialOptions, int initialSelection) {
title = "";
numberOfOptions = initialNumberOfOptions;
options = initialOptions;
currentSelection = initialSelection;
}
void Menu::display() {
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), {0, 0});
for(int i = 0; i < 10; i++) {
cout << " " << endl;
}
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), {0, 0});
if(title != "") {
cout << title << endl << endl;
}
for(int i = 0; i < numberOfOptions; i++) {
if(i == currentSelection - 1) {
cout << "[ " << options[i] << " ]" << endl;
} else {
cout << options[i] << endl;
}
}
waitForInput();
}
void Menu::waitForInput() {
char input;
while(!kbhit());
input = getch();
if(input == 72 && currentSelection > 1) {
currentSelection--;
} else if (input == 80 && currentSelection < numberOfOptions) {
currentSelection++;
} else if (input == 13) {
if(currentSelection == 1) {
executeOptionAction(1);
}
return;
}
display();
}
void Menu::attachOptionAction(int option, std::function<void()> function) {
optionActions[option] = function;
}
void Menu::executeOptionAction(int option) {
(optionActions[option])();
}
test.cpp
#include "Menu.h"
#include <unistd.h>
#include <iostream>
#include <iomanip>
#include <map>
void test() {
cout << "Hello, World!";
}
int main() {
map<int, string> options;
options[0] = "Play";
options[1] = "Help";
options[2] = "Quit";
Menu menu(3, options, 1);
menu.title = "ASCII Game Library 2015";
menu.display();
void (*actionPointer)() = NULL;
menu.attachOptionAction(1, (*actionPointer));
return 0;
}
This is wrong. I'm not even sure what's that supposed to be.
map<int, void (*std::function<void()>)> optionActions;
It should be:
map<int, std::function<void()>> optionActions;
This here is also wrong. It would be correct if you hadn't imported std into your current namespace.
void attachOptionAction(int option, void (*function)());
It should be:
void attachOptionAction(int option, const std::function<void()> & action);
This here is also wrong. You can't name your argument function after you imported std into your namespace.
void Menu::attachOptionAction(int option, std::function<void()> function)
It should be:
void Menu::attachOptionAction(int option, const std::function<void()> & action)
This here is also wrong. You don't check if the function exists or that a valid function pointer was assigned to it. Which you haven't.
(optionActions[option])();
It should be:
// Attempt to find the action!
map<int, std::function<void()>>::iterator action = optionActions.find(option);
// Did we find anything?
if (action == optionActions.end())
{
return;
}
// Is the function assigned to this action valid?
if (action->second)
{
action->second();
}
You are attaching a null function pointer to an action and try to call it. And since there's no validation it does exactly that. Which is why you get that exception:
void (*actionPointer)() = NULL;
menu.attachOptionAction(1, (*actionPointer));
But I'm not even sure how even managed to compile it :/
EDIT:
I hope you can find this example to be informative on what you're looking for.
#include <map>
#include <string>
#include <cstdlib>
#include <iostream>
#include <functional>
class Menu
{
protected:
typedef std::function<int (Menu &)> Callback;
typedef std::map<int, Menu> SubMenus;
public:
Menu()
: m_Id(0), m_Name(""), m_Handler(nullptr)
{
}
Menu(int id, const std::string & name, Callback clbk)
: m_Id(id), m_Name(name), m_Handler(clbk)
{
}
Menu & operator [] (int id)
{
return m_Childrens.at(id);
}
int Enter()
{
int result = 0;
if (m_Handler)
result = m_Handler(*this);
return result;
}
void Insert(const Menu & menu)
{
m_Childrens[menu.m_Id] = menu;
}
void Insert(int id, const std::string & name, Callback clbk)
{
m_Childrens[id] = Menu(id, name, clbk);
}
void Remove(int id)
{
m_Childrens.erase(id);
}
int GetId() const
{
return m_Id;
}
const std::string & GetName() const
{
return m_Name;
}
const Callback & GetHandler() const
{
return m_Handler;
}
bool IsChildren(int id) const
{
return (m_Childrens.find(id) != m_Childrens.cend());
}
Menu & GetChildren(int id)
{
return m_Childrens.at(id);
}
const SubMenus & GetChildrens() const
{
return m_Childrens;
}
private:
int m_Id;
std::string m_Name;
Callback m_Handler;
SubMenus m_Childrens;
};
void ClearScreen()
{
system("cls");
}
int SharedMenuDisplay(const Menu & menu)
{
ClearScreen();
std::cout << "Welcome to " << menu.GetName() << std::endl;
for (const auto & m : menu.GetChildrens())
{
std::cout << "> " << m.second.GetId() << " - " << m.second.GetName() << std::endl;
}
std::cout << "> 0 - Go Back" << std::endl;
std::cout << "Please select a sub menu: ";
int choice;
std::cin >> choice;
return choice;
}
int Menu_Home(Menu & menu)
{
int choice;
int result = 0;
do {
ClearScreen();
std::cout << "Welcome to " << menu.GetName() << std::endl;
for (const auto & m : menu.GetChildrens())
{
std::cout << "> " << m.second.GetId() << " - " << m.second.GetName() << std::endl;
}
std::cout << "> 0 - To Leave" << std::endl;
std::cout << "Please select a sub menu: ";
std::cin >> choice;
if (choice != 0 && menu.IsChildren(choice))
result = menu.GetChildren(choice).Enter();
} while (choice != 0);
return result;
}
int Menu_A(Menu & menu)
{
int choice;
int result = 0;
do {
choice = SharedMenuDisplay(menu);
if (choice != 0 && menu.IsChildren(choice))
result = menu.GetChildren(choice).Enter();
} while (choice != 0);
return result;
}
int Menu_A_SubMenu_X(Menu & menu)
{
ClearScreen();
std::cout << "You have selected " << menu.GetName() << std::endl;
std::cout << "> Type something and press Enter to go back..." << std::endl;
std::string str;
std::cin >> str;
return 0;
}
int Menu_A_SubMenu_Y(Menu & menu)
{
ClearScreen();
std::cout << "You have selected " << menu.GetName() << std::endl;
std::cout << "> Type something and press Enter to go back..." << std::endl;
std::string str;
std::cin >> str;
return 0;
}
int Menu_A_SubMenu_Z(Menu & menu)
{
ClearScreen();
std::cout << "You have selected " << menu.GetName() << std::endl;
std::cout << "> Type something and press Enter to go back..." << std::endl;
std::string str;
std::cin >> str;
return 0;
}
int Menu_B(Menu & menu)
{
int choice;
int result = 0;
do {
choice = SharedMenuDisplay(menu);
if (choice != 0 && menu.IsChildren(choice))
result = menu.GetChildren(choice).Enter();
} while (choice != 0);
return result;
}
int Menu_B_SubMenu_X(Menu & menu)
{
ClearScreen();
std::cout << "You have selected " << menu.GetName() << std::endl;
std::cout << "> Type something and press Enter to go back..." << std::endl;
std::string str;
std::cin >> str;
return 0;
}
int Menu_B_SubMenu_Y(Menu & menu)
{
ClearScreen();
std::cout << "You have selected " << menu.GetName() << std::endl;
std::cout << "> Type something and press Enter to go back..." << std::endl;
std::string str;
std::cin >> str;
return 0;
}
int Menu_B_SubMenu_Z(Menu & menu)
{
ClearScreen();
std::cout << "You have selected " << menu.GetName() << std::endl;
std::cout << "> Type something and press Enter to go back..." << std::endl;
std::string str;
std::cin >> str;
return 0;
}
int Menu_C(Menu & menu)
{
ClearScreen();
std::cout << "You have selected " << menu.GetName() << std::endl;
std::cout << "> Type something and press Enter to go back..." << std::endl;
std::string str;
std::cin >> str;
return 0;
}
int main(int argc, char **argv)
{
Menu home(-1, "Home", &Menu_Home);
home.Insert(1, "Menu Item A", &Menu_A);
home.Insert(2, "Menu Item B", &Menu_B);
home.Insert(3, "Menu Item C", &Menu_C);
home.GetChildren(1).Insert(1, "Sub Menu Item X", &Menu_A_SubMenu_X);
home.GetChildren(1).Insert(2, "Sub Menu Item Y", &Menu_A_SubMenu_Y);
home.GetChildren(1).Insert(3, "Sub Menu Item Z", &Menu_A_SubMenu_Z);
home[2].Insert(1, "Sub Menu Item X", &Menu_B_SubMenu_X);
home[2].Insert(2, "Sub Menu Item Y", &Menu_B_SubMenu_Y);
home[2].Insert(3, "Sub Menu Item Z", &Menu_B_SubMenu_Z);
return home.Enter();
}

C++ Why doesn't my constructor work?

I'm using visual c++ 2010 and I'm having trouble with class constructors. I've written it exactly as my instructor described and I can't seem to figure out why it wont compile.
#include <iostream>;
using namespace std;
class Account
{
public:
Insert other functions here...
Account(float b)
{
Balance = b;
}
private:
float &Balance;
}
Int main()
{
float withdraw,deposit;
Account myAccount(100.00);
cout << "Enter the amount you would like to withdraw:" << endl;
cin >> withdraw;
MyAccount.debt(withdraw);
cout << "Your balance is now "<< endl;
MyAccount.showAccountInfo();
cout << endl;
cout << "Enter the amount you would like to deposit: " << endl;
cin >> deposit;
myAccount.credit(deposit);
cout << "Your balance now is " << endl;
MyAccount.showAccountInfo();
cout << endl;
return 0;
}
It is possible that you have declared the member Balance as a reference and you are calling the constructor with a constant (i.e. 100.00), you must pass a variable name to the contructor or declare the member without the reference operator.
If you need the balance in different parts of the process you could try it with dynamic memory.
For instance:
class Account
{
public:
Insert other functions here...
Account(float* b)
{
Balance = b;
}
private:
float* Balance;
}
Int main()
{
float withdraw,deposit;
Account myAccount(new float(100.0));
cout << "Enter the amount you would like to withdraw:" << endl;
cin >> withdraw;
MyAccount.debt(withdraw);
cout << "Your balance is now "<< endl;
MyAccount.showAccountInfo();
cout << endl;
cout << "Enter the amount you would like to deposit: " << endl;
cin >> deposit;
myAccount.credit(deposit);
cout << "Your balance now is " << endl;
MyAccount.showAccountInfo();
cout << endl;
return 0;
In the updating balance method, you should unreference the pointer:
For instance...
void debt(float withdraw){
*balance -= withdraw;
}
Thanks, Regards.