Displaying enumeration values from functions - c++

The idea is to display all the data from the collected from the user in a tabular format according to the structures and enumerations defined. I've gotten some warnings about the use of the switch statement but the most inhibiting thing seems to be the use of the "s.width" when attempting to display the values. When I attempt to compile it advises that it's expecting a semicolon before s in s.width and it continues to move the semicolon to the next value. Is there something incorrect about the way I am referencing the values from my enumerations?
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
//TODO 1: ShapeKind Enumeration goes here
enum class ShapeKind{
CIRCLE,SQUARE,RECTANGLE
};
//TODO 2: Shape Structure goes here
struct Shape{
ShapeKind kind;
double length, width;
};
// Function prototypes and definitions
double area(Shape s);
//TODO 3: area() definition goes here
double area(Shape s){
double a;
switch(s.kind){
case ShapeKind::CIRCLE:
return a= (s.length * s.width * 3.14) /4 ;
case ShapeKind::SQUARE:
return a = s.length *s.length;
case ShapeKind::RECTANGLE:
return a = s.length * s.width;
}
}
double perimeter(Shape s);
//TODO 4: perimeter() definition goes here
double perimeter(Shape s){
double p;
switch(s.kind){
case ShapeKind::CIRCLE:
return p= s.length * 3.14;
case ShapeKind::SQUARE:
return p = s.length *4;
case ShapeKind::RECTANGLE:
return p = 2 *(s.length + s.width);
}
}
string nameOf(Shape s);
//TODO 5: nameOf() definition goes here
string nameof(Shape s){
switch(s.kind){
case ShapeKind::CIRCLE:
return "Circle";
case ShapeKind::SQUARE:
return "Square";
case ShapeKind::RECTANGLE:
return "Rectangle";
}
}
void promptAndReadInputFor(Shape& shape);
//TODO 6: promptAndReadInputFor() definition goes here
void promptAndReadInputFor(Shape& s){
switch(s.kind){
case ShapeKind::CIRCLE:
cout <<"Enter the diameter or a circle: "<< endl;
cin >> s.length;
s.width =s.length;
case ShapeKind::SQUARE:
cout << "Enter the length of one side: "<< endl;
cin >>s.length;
s.width=s.length;
case ShapeKind::RECTANGLE:
cout << "Enter the length and width: "<< endl;
cin >>s.length>>s.width;
if (s.length == s.width)
{
s.kind = ShapeKind::SQUARE;
}
}
};
// The main function
int main() {
// Shape objects
Shape circle = { ShapeKind::CIRCLE, 0, 0 };
//TODO 7: define two more shape objects: a square and and a rectangle
Shape square= {ShapeKind::SQUARE, 0, 0};
Shape rectangle ={ShapeKind::RECTANGLE, 0, 0};
//TODO 8: Call the promptAndReadInputFor() function on each of the above three shapes
promptAndReadInputFor(circle);
promptAndReadInputFor(square);
promptAndReadInputFor(rectangle);
//TODO 9: Print a out a report of these shapes in a table-like format
cout << setw(4) << "Shape" << setw(4) << "Width" << setw(4) << "Height" << setw(4) << "Perimeter"<< setw(4) << "Area"<<endl;
cout << setw(4) << nameOf(circle) << setw(4) s.width << setw(4) s.length << setw(4) perimeter(circle)<< setw(4) << area(circle)<< endl;
return 0;
}

You are missing a <<
cout << setw(4) << nameOf(circle) << setw(4) s.width << setw(4) s.length
// ^HERE there should probably be '<<'
<< setw(4) perimeter(circle)<< setw(4) << area(circle)<< endl;

In your code, your function declaration of nameOf and definition nameof are different;
should be same
string nameOf(Shape s);
string nameof(Shape s) {} // not the same in your code
and one more change needed,
you have not declared any local s variable inside main, you are declared as circle your Shape object.

Fixed all the bugs. Wanna thank you for your help and also pass on some info for anyone that might need help with something similar. My promptAndReadInputFor function was missing a return statement for each case which caused the function to never end. Both answers I received were correct as the references made for "s.width, s.etc" weren't applicable within the scope of the main function so changing them to "circle, square, etc" which were the objects created to be used solved the issue. I appreciate the assistance you guys provided. Felt great to finally solve this problem.

Related

c++ entering values two times instead of one

I have to solve this " create class for describing triangle and trapeze with ability to return values and finding S of the figures.. declare function which allows comparing S of the both figures.. in main function declare object triangle and trapeze and compare their areas .. " - im trying to translate it from Bulgarian to English sorry if its not translated correctly ..
Anyways I came up with a solution, but when it asks me to enter value for trapeze x2 times and I can't understand why... it always takes the first 3 entered numbers but I want it to ask for input only once .. sorry if the answer is obvious
//
// main.cpp
// compare S of 2 figures
//
// Created by Георгиос Семерджиев on 17/05/22.
//
#include <iostream>
#include <cmath>
using namespace std;
class Trap // trap class with declared functions inside
{
protected:
double a, c, h;
void setValueTrap();
public:
Trap();
void Print();
virtual double S();
}; // end trap class
class Triangle : public Trap // triangle class with declared function for finding s() print and setting value
{
double b;
void setValueTriangle();
public:
Triangle();
void Print();
virtual double S();
double p(); // returning P/2
}; // end triangle class
// trap functions ...
Trap:: Trap()
{
setValueTrap();
}
void Trap::setValueTrap() // trap input function
{
cout << "Trap enter a = "; cin >> a;
cout << "Trap enter c = "; cin >> c;
cout << "Trap enter h = "; cin >> h;
cout << endl;
}
double Trap::S() // trap calculating and returning s()
{
return ( (a+c) * h ) / 2;
}
void Trap::Print() // printing S() for trap
{
cout << "Trap S = " << S();
cout << endl;
}
// Triangle functions ..
Triangle::Triangle():Trap()
{
setValueTriangle();
}
void Triangle::setValueTriangle() // setting value for triangle a,b,c
{
cout << "Triangle a = "; cin >> a;
cout << "Triangle b = "; cin >> b;
cout << "Triangle c = "; cin >> c;
cout << endl;
}
double Triangle::p() // returning P / 2 = p
{
return (a+b+c) / 2;
}
double Triangle::S() // calculating S() of triangle
{
return sqrt(p() * (p() - a) * (p()-b) * (p()-c));
}
void Triangle::Print()
{
cout << "Triangle S = " << S();
cout << endl;
}
// creating function to compare Trap S() and Triangle S()
bool Compare (Trap *F1, Trap *F2)
{
return F1 -> S() < F2 -> S();
} // compare function
int main()
{
Trap* trap = new Trap();
Triangle* triangle = new Triangle();
trap -> Print(); triangle -> Print();
cout << endl;
if (Compare(trap, triangle))
cout << "the Trap S < Triangle S.." << endl;
else
{
cout << "The Trap S > Triangle S.." << endl;
}
return 0;
}
For the Triangle constructor you have:
Triangle::Triangle():Trap()
{
setValueTriangle();
}
That will explicitly invoke the Trap constructor which read input. Then you will read the input for the triangle.
It's often not a good idea to read input in a constructor. It's usually better to only do basic initialization in the constructor and then get input using the fully constructed object.
Note that even if you don't have the explicit invokation of the Trap constructor, this will happen implicitly.
Triangle inherits from Trap, and both of their constructors are called when constructing Triangle object. To avoid this set up a virtual function setValue and call it only in Trap constructor.

CPP Guessing Game not working, its stops after i enter the name

I'm trying to make this kina guess game on C++, I'm a beginner and still learning.
What I'm trying to achieve is a guessing game of two const names, is very simple without errors but it's not working after I enter something. it should report until I find the correct name. Please also I don't want to change the structure of the code, just find why isn't working.
#include <iostream>
#include <string>
using namespace std;
struct Vlerat {
string guess01 = "Resul";
string guess02 = "Rejan";
int numruesi = 0;
};
int main() {
Vlerat funksioni;
string nameGuess;
int nameOkay = 0;
cout << "Gjej njerin prej dy emrava te fshehura." << endl;
cout << "Ndihm: Fillojn me Shkronjen 'R', dhe pas asaj vjen edhe nje shkronj 'e'" << endl;
do {
cout << "Shkruaj Emrin > "; cin >> nameGuess;
if (nameGuess == funksioni.guess01){
cout << "Ju e keni gjetur emrin e njerit nga personat duke provuar gjithesej:";
cout << funksioni.numruesi++ << " here." << endl;
nameOkay++;
}
if (nameGuess == funksioni.guess02) {
cout << "Ju e keni gjetur emrin e njerit nga personat duke provuar gjithesej:";
cout << funksioni.numruesi++ << " here." << endl;
nameOkay++;
}
funksioni.numruesi++;
} while(nameOkay = 0);
}
You should change while(nameOkay = 0); to while(nameOkay == 0);.
Because = is an assignment, but == is operator of comparing (equality)
Read about it here
And here

C++ Can't figure out output for a class that holds player information. It outputs garbage

I've been pulling my hair out trying to figure out this program. The class has to hold 3 player's info and output their info. My output function is not outputting from my set/get functions. Also, if I output the array indexes the program crashes (that's the array indexes are commented out in the Output function).
edit: I'll just show one profile to keep the code smaller
Any help is appreciated.
#include <cstdlib>
#include <iostream>
using namespace std;
class PlayerProfile
{
public:
void output();
void setName1(string newName1); //player's name
void setPass1(string newPass1); //player's password
void setExp1(int newExp1); //player's experience
void setInv1(string newInv1[]); //player's inventory
void setPos1(int newX1, int newY1); //player's position
string getName1();
string getPass1();
int getExp1();
string getInv1();
int getPos1();
private:
string name1;
string pass1;
int exp1;
string inv1[];
int x1;
int y1;
};
int main(int argc, char *argv[])
{
PlayerProfile player;
cout << "This program generates three player objects and displays them." << endl;
cout << endl;
player.output();
system("PAUSE");
return EXIT_SUCCESS;
}
void PlayerProfile::setName1(string newName1)
{
newName1 = "Nematocyst";
name1 = newName1;
}
void PlayerProfile::setPass1(string newPass1)
{
newPass1 = "obfuscator";
pass1 = newPass1;
}
void PlayerProfile::setExp1(int newExp1)
{
newExp1 = 1098;
exp1 = newExp1;
}
void PlayerProfile::setInv1(string newInv1[])
{
newInv1[0] = "sword";
newInv1[1] = "shield";
newInv1[2] = "food";
newInv1[3] = "potion";
inv1[0] = newInv1[0];
inv1[1] = newInv1[1];
inv1[2] = newInv1[2];
inv1[3] = newInv1[3];
}
void PlayerProfile::setPos1(int newX1, int newY1)
{
newX1 = 55689;
x1 = newX1;
newY1 = 76453;
y1 = newY1;
}
string PlayerProfile::getName1()
{
return name1;
}
string PlayerProfile::getPass1()
{
return pass1;
}
int PlayerProfile::getExp1()
{
return exp1;
}
string PlayerProfile::getInv1()
{
return inv1[0], inv1[1], inv1[2], inv1[3];
}
int PlayerProfile::getPos1()
{
return x1, y1;
}
void PlayerProfile::output()
{
cout << "Player Info - " << endl;
cout << "Name: " << name1 << endl;
cout << "Password: " << pass1 << endl;
cout << "Experience: " << exp1 << endl;
cout << "Position: " << x1 << ", " << y1 << endl;
cout << "Inventory: " << endl;
/*cout << inv1[0] << endl;
cout << inv1[1] << endl;
cout << inv1[2] << endl;
cout << inv1[3] << endl; */
}
This is the output that I am getting:
This program generates three player objects and displays them.
Player Info -
Name:
Password:
Experience: -2
Position: 3353072, 1970319841
Inventory:
Press any key to continue . . .
I'm sorry if I sound like an idiot, this is the first time I have programmed with classes and I am very confused.
First:
You do not have a constructor declared or defined in your class so when you compile, the compiler provides you with a default constructor.
The line
PlayerProfile player;
calls the default constructor provided by the compiler. This default constructor only allocates memory for your class member variables, but does not set their values. This is why name1, pass1, exp1, x1, y1 are not outputting what you expect.
Second:
C++ will not call get or set functions for you, and I think you are misunderstanding how c++ functions work.
this
void PlayerProfile::setName1(string newName1)
{
name1 = newName1;
}
is a function definition. You do not need to assign newName1 inside the function. It's value is passed to the function when a line like
setName1("Nematocyst");
is executed.
If you write a constructor, you can use it to call your set functions, and pass them the values you want to set member variables to.
If you do not want to write a constructor, you can call class functions/methods from main with:
player.setName1("Nematocyst");
Third:
Your program crashes because you are not using arrays properly. Here is a tutorial on how to declare an array and access it's contents.
Generally, I think you are trying to run before you know how to walk. Try not to get frustrated. Learn how arrays work, how functions work, and then how classes work. I hope this is not your homework assignment!

Reiterating through class vectors C++

I am still wrapping my head around classes and am still new to C++. My assignment is:
Create three small classes unrelated by inheritance - classes
Building, Car and Bicycle. Give each class some unique appropriate
attributes and behaviors that it does not have in common with other
classes.
Write an abstract class CarbonFootprint with only a pure virtual
getCarbonFootprint method.
Have each of your classes inherit from that abstract class and
implement the getCarbonFootprint method to calculate an appropriate
carbon footprint for that class (check out a few websites that explain
how to calculate carbon footprints).
Write an application that creates objects of each of the three
classes, places pointers to those objects in a vector of
CarbonFootprint pointers, then iterates through the vector,
polymorphically invoking each object's getCarbonFootprint method.
For each object, print some identifying information and the object's
carbon footprint.
I am having trouble trying to figure out how to iterate through my vector <CarbonFootPrint>. I also do not know if the objects being created are actually being put into this vector. My code so far is:
#include <iostream>
#include <vector>
using namespace std;
class CarbonFootPrint
{
//class declarations
public:
virtual double getCarbonFootPrint();
};
//class implementation
double CarbonFootPrint::getCarbonFootPrint()
{
return 0;
}
class Building : CarbonFootPrint
{
//class declarations
public:
Building(double e = 0, int m = 12); //constructor
~Building(); //destructor
double setElectric();
virtual double getCarbonFootPrint();
private:
double electric;
int months;
};
//class implementation
Building::Building(double e, int m)
{
electric = e;
months = m;
}
Building::~Building()
{
}
double Building::setElectric()
{
cout << "Enter your monthly electric in KWH: " << endl;
cin >> electric;
return electric;
}
double Building::getCarbonFootPrint()
{
//I would like to print out the variable information for each object created
//and then
cout << "The carbon footprint for this house is " << endl;
//when it iterates through the vector.
return(electric * months);
}
class Car : CarbonFootPrint
{
public:
Car(double = 0, double = 0); //constructor
~Car(); //destructor
double setYearlyMiles();
double setAverageMPG();
virtual double getCarbonFootPrint();
private:
double yearlyMiles, averageMPG;
int co2 = 9;
};
//class implementation
Car::Car(double ym, double mpg)
{
yearlyMiles = ym;
averageMPG = mpg;
}
Car::~Car()
{
}
double Car::setYearlyMiles()
{
cout << "Enter in your yearly miles: " << endl;
cin >> yearlyMiles;
return yearlyMiles;
}
double Car::setAverageMPG()
{
cout << "Enter in your average miles per gallon: " << endl;
cin >> averageMPG;
return averageMPG;
}
double Car::getCarbonFootPrint()
{
//I would like to print out the variable information for each object created
//and then
cout << "The carbon footprint for this car is " << endl;
//when it iterates through the vector.
return((yearlyMiles * averageMPG) * co2);
}
class Bicycle : CarbonFootPrint
{
public:
Bicycle(double = 0, int = 34); //constructor
~Bicycle(); //destructor
double setMiles();
virtual double getCarbonFootPrint();
private:
int calories;
double miles;
};
//class implementation
Bicycle::Bicycle(double m, int c)
{
miles = m;
calories = c;
}
Bicycle::~Bicycle()
{
}
double Bicycle::setMiles()
{
cout << "Enter in number of miles: " << endl;
cin >> miles;
return miles;
}
double Bicycle::getCarbonFootPrint()
{
//I would like to print out the variable information for each object created
//and then
cout << "The carbon footprint for this bicycle is " << endl;
//when it iterates through the vector.
return (miles * calories);
}
Here is my main program:
int main()
{
vector <CarbonFootPrint> *list;
int answer, i;
cout << "Welcome to the Carbon Footprint Calculator!\n" << endl;
do
{
cout << "Main Menu\n" << endl;
cout << "1: Set house info.\n" << endl;
cout << "2: Set car info.\n" << endl;
cout << "3: Set bicycle info.\n" << endl;
cout << "4: Get carbon footprint for all items set.\n" << endl;
cin >> answer;
switch (answer)
{
case 1:
{
cout << "\n" << endl;
Building *anotherBuilding;
anotherBuilding = new Building;
anotherBuilding->setElectric();
cout << "\n" << endl;
break;
}
case 2:
{
cout << "\n" << endl;
Car *anotherCar;
anotherCar = new Car;
anotherCar->setYearlyMiles();
anotherCar->setAverageMPG();
cout << "\n" << endl;
break;
}
case 3:
{
cout << "\n" << endl;
Bicycle *anotherbike;
anotherbike = new Bicycle;
anotherbike->setMiles();
cout << "\n" << endl;
break;
}
case 4:
{
//have it iterate through the vector and print out each carbon footprint.
break;
}
default:
{
cout << answer << " is not a valid option" << endl;
break;
}
}
}
while (answer != 4);
system("pause");
return 0;
}
Any help or guidance is greatly appreciated! Thank you for your time!
Re: your comments on R Sahu's post (I'm too new to be allowed to comment on other posts)
You cannot access the base class because it has defaulted to private,
class Building : CarbonFootPrint
class Car : CarbonFootPrint
class Bicycle : CarbonFootPrint
are all inheriting from CarbonFootPrint privately, which represents a "has-a" relationship, in this case although semantically a car has-a carbon foot print you're actually trying to make an "is-a" relationship, as these are all objects that implement the base class, possibly a better name for CarbonFootPrint could be CarbonFootPrintProducer.
The fix here is simply make them all publically inherited
class Name : public Base
You missed a crucial thing from:
Write an application that creates objects of each of the three classes, places pointers to those objects in a vector of CarbonFootprint pointers, then iterates through the vector, polymorphically invoking each object's getCarbonFootprint method.
Instead of
vector <CarbonFootPrint> *list; // Pointer to a vector of CarbonFootPrint objects.
You need to use
vector <CarbonFootPrint*> list; // A vector of CarbonFootPrint pointers.
Instead of
{
cout << "\n" << endl;
Building *anotherBuilding;
anotherBuilding = new Building;
anotherBuilding->setElectric();
cout << "\n" << endl;
break;
}
Use
{
cout << "\n" << endl;
Building *anotherBuilding;
anotherBuilding = new Building;
anotherBuilding->setElectric();
// Add the pointer to the list of pointers.
list.push_back(anotherBuilding);
cout << "\n" << endl;
break;
}
Make similar changes to the other object types.
At the end, call CarbonFootPrint() on the objects:
for (auto item : list )
{
item->CarbonFootPrint();
}
and delete the objects:
for (auto item : list )
{
delete item;
}
R Sahu covered almost all of it, the only bit I see remaining is;
Write an abstract class CarbonFootprint with only a pure virtual getCarbonFootprint method.
to which your class is not abstract as the function is not pure virtual, to do this simply add = 0
virtual double getCarbonFootPrint() = 0;
Pure virtual functions are ones that don't count as implemented, any class containing a pure virtual function is called "abstract" and cannot be instantiated. In this case it would have helped you identify your vector of CarbonFootPrint rather than CarbonFootPrint* to them, as the instantiations would be picked up by the compiler, although knowing template compiler errors you'd have had a couple hundred lines of error message for this simple mistake.
For full disclosure: a pure virtual function can actually be defined, e.g.;
virtual double getCarbonFootPrint() = 0;
double CarbonFootPrint::getCarbonFootPrint()
{
// some code
return 0;
}
which can then be called from any derived class
double Building::getCarbonFootPrint()
{
return CarbonFootPrint::getCarbonFootPrint();
}
This is legal C++, allows you to define a default implementation, and still CarbonFootprint is an abstract class.

How to use enumeration types in C++?

I do not understand how to use enumeration types. I understand what they are, but I don't quite get their purpose.
I have made a program that inputs three sides of a triangle and outputs whether or not they are isosceles, scalene, or equilateral. I'm suppose to incorporate the enumeration type somewhere, but don't get where and how to use them. Any help would be appreciated.
#include <iostream>
using namespace std;
enum triangleType {scalene, isosceles, equilateral, noTriangle};
triangleType triangleShape(double x, double y, double z);
void printTriangleShape(triangleType shape);
int main()
{
double x, y, z;
triangleType scalene, isosceles, equilateral, noTriangle;
cout << "Please enter the three sides of a triangle:" << endl;
cout << "Enter side 1: ";
cin >> x;
cout << endl;
cout << "Enter side 2: ";
cin >> y;
cout << endl;
cout << "Enter side 3: ";
cin >> z;
cout << endl;
triangleType t = triangleShape(x, y, z);
printTriangleShape(t);
return 0;
}
triangleType triangleShape(double x, double y, double z)
{
triangleType scalene, isoceles, equilateral, noTriangle;
if (((x+y) > z) && ((x+z) > y) && ((y+z) > x))
{
cout << "You have a triangle!" << endl;
if (x == y && y == z)
return equilateral;
else if (x == y || x == z || y == z)
return isosceles;
else
return scalene;
}
else if ((x+y) <= z || ((x+z) <= y) || ((y+z) <= x))
return noTriangle;
}
void printTriangleShape(triangleType shape)
{
switch (shape)
{
case scalene: cout << "Your triangle is Scalene!" << endl;
break;
case isosceles: cout << "Your triangle is an isosceles!" << endl;
break;
case equilateral: cout << "Your triangle is an equilateral!" << endl;
break;
}
}
It's a value, and you probably want to return it from your function.
Try:
triangleType triangleShape(double x, double y, double z) {
if (...) {
return scalene;
} else if (...) {
return isosceles.
} else if (...) {
return equilateral
} else {
return noTriangle;
}
}
Note, you can print the result, but it will print as an integer:
scalene = 0, isosceles = 1, ...
Edit, for printing you may want to do this:
void printTriangleShape(triangleType shape) {
switch (shape) {
case scalene:
cout << "Your triangle is Scalene!" << endl;
break;
case isosceles:
cout << "Your triangle is isosceles!" << endl;
break;
...;
}
}
In C enums make debugging easier because often debuggers print the name value rather than a numeric value. They also allow the compiler to enforce places where it can determine that an invalid value is being stored into an enum variable.
In C++ there is also another benifit, which is that you can use enum types in overloads.
For instance, you could:
ostream & operator<<(ostream & ostr, triangleType t) {
string s;
switch (t) {
case scalene:
s = "scalene";
break;
case isosceles:
s = "isosclese";
break;
case equilateral:
s = "equilateral";
break;
case noTriangle:
s = "noTriangle";
break;
default:
s = "error bad triangle type";
break;
}
return cout << s;
}
and then in main do
cout << "Your triangle is" << t << endl;
An enumeration can be used to identify 'types' of objects, as you are in your case.
For example, your triangle shape method could return a triangleType and that way you could do all of the cout << "..." in your main method and separate the display logic from the triangle object.
The idea is to replace using numbers (1,2,3...) that don't explain their meaning with tags that do have meaning (red, green, blue...). Numbers used in code that only you understand the meaning of are called "magic numbers" and should be avoided since it keeps others from understanding your code.
An enum is a new type in c++. Using this type creates additional type safety as you are only allowed to use the values that are defined for that enum. Enum values will get numbered automatically unless you specify a value yourself, which should be rarely needed. An example:
enum Color { Red, Green, Blue }; // Red = 0, Green = 1, Blue = 2
enum Shape { Circle, Square }; // Circle = 0, Square = 1
int printColor(Color c)
{
// do something with the color here, for example print it.
switch(c)
{
case Red:
cout << "Red";
break;
case Green:
cout << "Green";
break;
case Blue:
cout << "Blue";
break;
}
}
int main(int argc, char* argv[])
{
printColor(Red); // works
printColor(0); // will give an error or warning in C++.
// However, C does less type checking and allows this.
printColor(Circle);
// error, the type is wrong even if the values are identical.
}
You get added type safety in the printColor(0) call -- c++ does additional type checking here, so you can't mistakenly put an invalid number in the call. You can of course achieve the same result with using #define for the values or even put them directly, but in that case the compiler won't be able to warn you if you put in invalid values.