Use of class and functions to provide info about rectangle - c++

One of my last assignments in C++ course is to write this program:
Reads a name for rectangle and just accepts names like "rec" name. for
example "rec john" "rec sally" ...
Then asks from bottom left point x
and y, as well as height and length. Then displays some info including
BL point, area, perimeter,...
Here is the code I wrote. I was working on it for a long time so now I really cannot see what is wrong with it. So please help.
My code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Point
{
private:
double px;
double py;
public:
void setX(const double x);
void setY(const double y);
double getX() const;
double getY() const;
};
class Rectangle
{
private:
string name;
Point blPoint;
double length, height;
public:
void setName(const string & inName);
void setBottomLeft(const double x, const double y);
void setDimensions(const double inLength, const double inHeight);
string getName() const;
Point getBottomLeft() const;
double getLength() const;
double getHeight() const;
double area() const;
double perimeter() const;
Point midPoint() const;
void scaleBy2();
void display() const;
};
void welcome();
bool read_rect (const string promptName, const string errInvalidName, const string errUsedName, string & inName, vector<Rectangle> & list);
void readXYcoord (const string promptPointxy, double & xcord, double & ycord);
void readLH (const string promptLH, double & inLength, double & inHeight);
void addRect (const string Name, double x, double y, double inLength, double inHeight, vector<Rectangle> & list);
void dis_rec(vector<Rectangle> & list);
int main()
{
Rectangle rec;
vector<Rectangle>list;
string prompt1stName = "Enter the name of the first rectangle: ";
string promptName = "Enter the name of the next rectangle: ";
string errInvalidName = "Invalid input. Type 'rec' following by the name or 'stop' if done.";
string errUsedName = "This name is already being used!";
string inName;
string Name;
double x,y,length,height;
welcome ();
bool read = read_rect (prompt1stName, errInvalidName, errUsedName, inName, list);
while (read == false)
{
cout << "Try again! ";
read = read_rect (prompt1stName, errInvalidName, errUsedName, inName, list);
}
if (inName != "stop")
{
int a = inName.length() - 4;
Name = inName.substr(4,a);
double x, y;
string promptPointxy = "Enter " + Name + "'s bottom left x and y coords: ";
readXYcoord (promptPointxy, x, y);
double length, height;
string promptLH= "Enter " + Name + "'s length and height: ";
readLH (promptLH, length, height);
addRect(Name, x, y, length, height, list);
}
while (inName !="stop")
{
cout << "Thank you! ";
bool read = read_rect(promptName, errInvalidName, errUsedName, inName, list);
while (read == false)
{
cout << "Try again! " <<endl;
read = read_rect(promptName, errInvalidName, errUsedName, inName, list);
}
if (inName != "stop")
{
int a = inName.length() - 4;
Name = inName.substr(4, a);
double x, y;
string promptPoint = "Enter " + Name + "'s bottom left x and y coords: ";
readXYcoord(promptPoint, x, y);
double inLength, inHeight;
string promptLength = "Enter " + Name + "'s length and height: ";
readLH(promptLength, inLength, inHeight);
addRect(Name, x, y, inLength, inHeight, list);
}
}
if (list.size() != 0)
{
dis_rec(list);
}
else
{
cout << "You have no rectangles in your list." << endl;
}
return 0;
}
void welcome()
{
cout << "Welcome! Create your own list of rectangles." << endl;
cout << "You will be asked to provide information about each rectangle in your list by name." << endl;
cout << "Type the word 'stop' for the rectangle name when you are done." << endl;
cout << endl;
}
bool read_rect (const string promptName, const string errInvalidName, const string errUsedName, string & inName, vector<Rectangle> & list)
{
cout << promptName;
getline(cin, inName);
if (inName == "stop")
{
return (true);
}
else if (inName.substr(0,4) != "rec ")
{
cout<< errInvalidName <<endl;
return (false);
}
else
{
int j = 0;
for (int i = 0; i < list.size(); i++)
{
if (inName == "rec " + list[i].getName())
{
j = j+1;
}
}
if (j == 0)
{
return(true);
}
if (j != 0)
{
cout << errUsedName;
return(false);
}
}
}
void readXYcoord (const string promptPointxy, double & xcord, double & ycord)
{
cout << promptPointxy;
cin >> xcord;
cin >> ycord;
}
void readLH (const string promptLH, double & inLength, double & inHeight)
{
cout<< promptLH;
cin >> inLength;
cin >> inHeight;
cout << endl;
while (inLength <= 0 || inHeight <= 0)
{
cout << "Make length and height positive values. Try again.";
cout << promptLH;
cin >> inLength;
cin >> inHeight;
cout << endl;
}
}
void addRect (const string Name, double x, double y, double inLength, double inHeight, vector<Rectangle> & list)
{
Rectangle rec;
rec.setName(Name);
rec.setBottomLeft(x, y);
rec.setDimensions(inLength, inHeight);
list.push_back(rec);
}
void dis_rec(vector<Rectangle> & list)
{
cout<<"You have "<<list.size()<<" rectangle(s) in your list: "<<endl;
for(int i=0; i<list.size(); i++)
{
cout<<"Rectangle '"<<list[i].getName()<<"': ";
list[i].display();
cout<<"After scale by 2:";
list[i].scaleBy2();
list[i].display();
}
}
void Point::setX(const double x)
{
px = x;
}
void Point::setY(const double y)
{
py = y;
}
double Point::getX() const
{
return (px);
}
double Point::getY() const
{
return (py);
}
void Rectangle::setName(const string & inName)
{
name = inName;
}
void Rectangle::setBottomLeft(const double x, const double y)
{
blPoint.setX(x);
blPoint.setY(y);
}
void Rectangle::setDimensions(const double inLength, const double inHeight)
{
length = inLength;
height = inHeight;
}
string Rectangle::getName() const
{
return (name);
}
Point Rectangle::getBottomLeft() const
{
return (blPoint);
}
double Rectangle::getLength() const
{
return (length);
}
double Rectangle::getHeight() const
{
return (height);
}
double Rectangle::area() const
{
return(length*height);
}
double Rectangle::perimeter() const
{
return ( (height*2)+(length*2));
}
Point Rectangle::midPoint() const
{
Point midPoint;
double mpx = blPoint.getX() + 0.5 * length;
double mpy = blPoint.getY() + 0.5 * height;
midPoint.setX(mpx);
midPoint.setY(mpy);
return(midPoint);
}
void Rectangle::scaleBy2()
{
double mx = blPoint.getX() + 0.5 * length;
double my = blPoint.getY() + 0.5 * height;
double newmdx = mx - length;
double newmdy = my - height;
length= 2* length;
height = 2* height;
blPoint.setX(newmdx);
blPoint.setY(newmdy);
}
void Rectangle::display() const
{
cout << " Location is (" << blPoint.getX() << ", " << blPoint.getY() << "), length is " << length << ", height is " << height << "; Area is " << area() << "; perimeter is " << perimeter() << ", midpoint is located at (" << midPoint().getX() << ", " << midPoint().getY() << ")" << endl;
}
here is the corrects output for correct input:
Welcome! Create your own list of rectangles.
You will be asked to provide information about each rectangle in your list by name.
Type the word 'stop' for the rectangle name when you are done.
Enter the name of the first rectangle: rec john
Enter john's bottom left x and y coords: 2
3
Enter john's length and height: 4
5
Thank you! Enter the name of the next rectangle: stop
You have 1 rectangle(s) in your list:
Rectangle 'john': Location is (2, 3), length is 4, height is 5; Area is 20, perimeter is 18, midpoint is located at (4, 5.5)
After scale by 2: Location is (0, 0.5), length is 8, height is 10; Area is 80, perimeter is 36, midpoint is located at (4, 5.5)
and here is my program's response:
Welcome! Create your own list of rectangles.
You will be asked to provide information about each rectangle in your list by na
me.
Type the word 'stop' for the rectangle name when you are done.
Enter the name of the first rectangle: rec john
Enter john's bottom left x and y coords: 2
3
Enter john's length and height: 4
5
Thank you! Enter the name of the next rectangle: Invalid input. Type 'rec' follo
wing by the name or 'stop' if done.
Try again!
Enter the name of the next rectangle: stop
You have 1 rectangle(s) in your list:
Rectangle 'john': Location is (2, 3), length is 4, height is 5; Area is 20; per
imeter is 18, midpoint is located at (4, 5.5)
After scale by 2: Location is (0, 0.5), length is 8, height is 10; Area is 80; p
erimeter is 36, midpoint is located at (4, 5.5)
As you can see, the only problem with this program is it displays the errInvalidName before asking for the next rectangle's name and info. what is wrong?

Your problem lies in combining cin >> with getline. Those two things aren't quite compatible, since they use a different mechanism to get the input. To fix the problem, after every cin >> in your program, you should also add cin.ignore().
The difference between those two methods is, that the overloaded operator >> gets the content before the newline character, and leaves the newline char in the buffer. When you use getline after doing >>, you extract the empty line. The empty line isn't "stop", and doesn't begin with "rec", so your program prompts an error.

Related

How to fix logical errors caused by incorrectly calling the functions in C++

The main goal of the program is to ask the user for a shape, dimensions of the said shape, and to calculate its' area. Using the functions is required.
I'm pretty sure the error lies within
int main()
and
void shape_output(...
void area_output(...
functions
#include <iostream>
#include <iomanip>
using namespace std;
void show_menu();
int user_choice();
int calc_area();
void shape_output(int);
void area_output(int);
int main()
{
int area;
int shape;
show_menu();
shape = user_choice();
area = calc_area();
shape_output(shape);
area_output(area);
return 0;
}
void show_menu()
{
cout << "Calculating the area of a shape\n\n"
<< "1. Circle\n"
<< "2. Rectangle\n"
<< "3. Square\n"
<< "4. Quit\n"
<< "Enter the number of your choice: " << endl;
}
int user_choice()
{
int CIRCLE = 1;
int SQUARE = 2;
int RECTANGLE = 3;
int QUIT = 4;
int choice;
cin >> choice;
if(choice < CIRCLE || choice > QUIT)
{
cout << "Please enter a valid menu choice" << endl;
cin >> choice;
}
return choice;
}
int calc_circle()
{
double radius,
area,
Pi = 3.14;
cout << "Enter the radius: ";
cin >> radius;
if(radius < 0)
{
cout << "Invalid, Try again: ";
cin >> radius;
}
area = Pi * radius * radius;
return area;
}
int calc_rectangle()
{
double height,
width,
area;
cout << "Enter the height: ";
cin >> height;
if(height < 0)
{
cout << "Invalid, Try again: ";
cin >> height;
}
area = height * width;
return area;
}
int calc_square()
{
double base,
area;
cout << "Enter the base: ";
cin >> base;
if(base < 0)
{
cout << "Invalid, Try again: ";
cin >> base;
}
area = base * base;
return area;
}
void quit()
{
cout << "Have a good day!\n";
}
int calc_area()
{
const int CIRCLE = 1;
const int SQUARE = 2;
const int RECTANGLE = 3;
const int QUIT = 4;
int choice = user_choice();
switch(choice)
{
case CIRCLE:
calc_circle();
break;
case SQUARE:
calc_square();
break;
case RECTANGLE:
calc_rectangle();
break;
case QUIT:
quit();
break;
default:
quit();
return 0;
break;
}
return choice;
}
void shape_output(int answer_choice)
{
cout << "Shape: " << answer_choice << endl;
}
void area_output(int answer_area)
{
cout << "Area: " << answer_area << endl;
}
I expect the output to be as such:
choose the shape:
number of the shape
specific dimension of a shape:
dimension(s)
shape: chosen shape
area: calculated area
but the output im getting is:
choose the shape:
number of the shape
number of the shape ( I have to put it in twice)
specific dimension of a shape:
dimension(s)
shape: number of the chosen shape, not the actual word
area: number of the chosen shape again.
Basically, I realized that my whole code was garbage, so I wrote it all from the start.
I had a lot of problems with correctly calling the functions and filling in the parameters and arguments, so I looked at some basic tutorials on functions and incoroporated them into my code.
Thanks everyone for the comments.
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
//Declaring function prototypes.
int question();
double option(int);
double input_fun();
double calc_circle(double);
double calc_square(double);
double calc_rect(double, double);
void output(double, double);
// main function where all the other functions are called from
int main()
{
int choice; // not related to `int choice` in `double question()`
// Data from question() function will be stored in `int choice`.
double option_case; // Data from `double option()` will be stored here.
choice = question();
option_case = option(choice);
output(choice, option_case);
return 0;
}
// function to prompt the user to choose a shape or quit
int question()
{
int choice;
cout << "Please choose a shape\n"
<< "Press 1 for CIRCLE\n"
<< "Press 2 for SQUARE\n"
<< "Press 3 for RECTANGLE\n"
<< "Press 4 to QUIT\n";
cin >> choice;
while (choice < 1 && choice > 4)
{
cout << "Invalid entry, Try again: \n";
cin >> choice;
}
return choice;
}
// Function to determine user's choice
double option(int choice)
{
double calc_area,
radius,
length,
width;
switch (choice) // Depending on user's choice, switch case decides what functions to call
{
case 1:
cout << "Enter Radius of the circle\n";
radius = input_fun();
calc_area = calc_circle(radius);
return calc_area;
break;
case 2:
cout << "Enter the base of the square\n";
length = input_fun();
calc_area = calc_square(length);
return calc_area;
break;
case 3:
cout << "Enter the length\n";
length = input_fun();
cout << "Enter the width\n";
width = input_fun();
calc_area = calc_rect(length, width);
return calc_area;
break;
case 4:
return 0;
break;
}
}
// This function is activated when user is prompted to
// enter the dimension of the chosen shape.
double input_fun()
{
double value;
cin >> value;
while (value < 0)
{
cout << "Value is lower than 0, try again: \n";
cin >> value;
}
return value;
}
//this function is activated if user chooses a circle.
double calc_circle(double radius)
{
double Pi = 3.14;
double power = 2.0;
return(Pi * pow(radius, power));
}
//this function is activated if user chooses a square.
double calc_square(double base)
{
double power = 2.0;
return(pow(base, power));
}
//this function is activated if user chooses a rectangle.
double calc_rect(double length, double width)
{
return(length * width);
}
void output(double shape, double area)
{
if(shape == 4)
cout << "Have a nice day\n";
else
{
cout << "Shape: " << shape << endl;
cout << "Area: " << area << endl;
}
}

Program error; need advice

Generally I have a class named "person" and its methods, print: to print the data, and is_better_than to find some max numbers. I cannot understand what is the problem. Any advice?
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
class person
{
private:
string name;
double weight;
double height;
public:
person(); //Constructor
bool is_better_than(person best);
void read();
void print();
void operator=(const person& b); //overloading operator
};
person::person()
{
string name = "";
double weight = 0;
double height = 0;
}
void person::print()
{
cout << name << "\nWeight: " << weight << "\nHeight: " << height << "\n";
}
void person::read()
{
cout << "Please enter person's name: ";
getline(cin, this->name);
cout << "Please enter person's weight: ";
cin >> this->weight;
cout << "Please enter person's height: ";
cin >> this->height;
string remainder;
getline(cin, remainder); //clear the buffer
}
bool person::is_better_than(person best)
{
if ((this->weight / pow(this->height,2) >= best.weight / (pow(best.height,2))) || best.weight == 0)
return true;
return false;
}
// iperfortosi telesti =
void person::operator=(const person & b)
{
this->name = b.name;
this->weight = b.weight;
this->height = b.height;
}
int main()
{
person maxBMI;
bool cont = true;
while (cont)
{
person newperson;
newperson.read();
if (newperson.is_better_than(maxBMI))
maxBMI = newperson;
cout << "More data? (y/n) ";
string answer;
getline(cin, answer);
if (answer != "y")
cont = false;
}
cout << "The person with maximum BMI (body mass index) is ";
maxBMI.print();
return 0;
}
Output:
Please enter person's name: Name
Please enter person's weight: 123
Please enter person's height: 123
More data? (y/n) n
The person with maximum BMI (body mass index) is
Weight: 1.7881e-307
Height: 2.0746e-317
Your default constructor does not work because it assigns to local variables and not to class variables. It should look like this:
person::person()
{
name = "";
weight = 0;
height = 0;
}
or better:
person::person() : name(""), weight(0.0), height(0.0) {}
With your default constructor, the class attributes remain uninitialized and the assumption that best.weightis initially zero, does not work.

Why does my program output a huge decimal?

Okay so i created program that simulates a landscaping company and so we have to calculate the cost of Sod and fence. So when i enter in both the length and width they out put huge decimals for example
Parkton Landscaping
Enter Length: 10
Enter width: 12
Lanscaping Costs
Sod = 6871947680.00
Fence = 19327352760.00
Press any key to continue . . .
Sod is suppose to = 56.40
and Fence is suppose to = 990.00
please help here is my code and both files
#include <iostream>
#include <iomanip>
using namespace std;
#include "c:\Users\barta\OneDrive\Documents\Visual Studio 2015\Projects\Project 6\Project 6\Geometry.h"
#include "Pricing.h"
int main()
{
int length, width;
Pricing landscape;
Geometry geo;
const double Fenceprice = 22.50;
const double Sodprice = .47;
cout << "\t Parkton Landscaping " << endl;
cout << "Enter Length: ";
cin >> length;
cout << "Enter width: ";
cin >> width;
//Pricing(length, width);
//geo.getLength();
//geo.getWidth();
std::cout << std::fixed << std::setprecision(2);
landscape.displayOutput();
cout << "Sod = " << landscape.getsodCost(length) << endl;
cout << "Fence = " << landscape.getFenceCost(Fenceprice) << endl;
system("pause");
return 0;
}
here is the header file:
#pragma once
class Geometry
{//an object is how you access the class
public:// where the public function definitions are created
Geometry();// Default Constructor
Geometry(int, int);
Geometry(int);
void setLength(int); //assigns length
void setWidth(int); //assigns width
void setSide(int); //assigns side
//Constructor function that recieves the values for the rectangle
//Constructor function that recieves values for the cube
int getLength(),
getWidth(),
getSide(),
getArea(),
getPerimeter(),
getSurfaceArea();
private: //where the private members are created
int length,
width,
side;
void checkNum(int); //function that checks to see if the number is less than 0
};
Geometry::Geometry()
{
length = length;
width = width;
side = 0;
}
Geometry:: Geometry(int length, int width) /*function recieves 2 intergers and calls checkNum to validate if */
{
setLength(length);
setWidth(width);
checkNum(length);
checkNum(width);
}
Geometry:: Geometry(int sides)
{
checkNum(sides);
setSide(sides);
}
int Geometry::getLength()
{
return length;
}
int Geometry::getWidth()
{
return width;
}
int Geometry::getSide()
{
return side;
}
int Geometry::getArea()
{
return length * width;
}
int Geometry::getPerimeter()
{
return 2 * (length + width);
}
int Geometry::getSurfaceArea()
{
return 6 * (side * side);
}
void Geometry::setLength(int len)
{
length = len;
checkNum(len);
}
void Geometry::setWidth(int widths)
{
width = widths;
checkNum(widths);
}
void Geometry::setSide(int s)
{
side = s;
checkNum(s);
}
void Geometry::checkNum(int num) //function checks to see if the number is less than zero
{
if (num <= 0)
{
cout << "!!!!!!!!WARNING!!!!!! this isnt a number" << " program will now exit......" << endl;
system("pause");
exit(1);
}
}
Header file #2
#include "Geometry.h"
class Pricing : Geometry
{
public:
Pricing();
Pricing(int length, int width);
double getsodCost(double);
double getFenceCost(double);
void displayOutput();
private:
};
Pricing::Pricing(int length, int width) :Geometry(length, width)
{
}
Pricing::Pricing()
{
}
double Pricing::getsodCost(double price)
{
getArea();
return getArea()*price;
}
double Pricing::getFenceCost(double price)
{
getPerimeter();
return getPerimeter()*price;
}
void Pricing::displayOutput()
{
cout << "\n\n";
cout << "\t Lanscaping Costs " << endl;
}
Because you never initialize the objects with valid values, meaning Geometry::width and Geogrpapy::length are uninitialized and have indeterminate values. Using them uninitialized leads to undefined behavior.

how to reference 3 functions while using struct

//I want to use 3 functions here with 1 struct that one function do the input
and one for calculation and the other one for out put but
I don't know how to reference //the variables in functions rec2 and rec3. I want to do it without using pointer
struct rectangle {
float length;
float width;
float area,perimeter;
};
rectangle rec1();
rectangle rec2();
rectangle rec3();
int main(){
rectangle f;
f = rec1();
f=rec2();
f = rec3();
return 0;
}
rectangle rec1(){
rectangle h;
cout<<"insert the length: ";
cin>>h.length;
cout<<"\ninsert width: ";
cin>>h.width;
return h;
}
rectangle rec2(){
rectangle z;
z.area=z.length*z.width;
z.perimeter=2*(z.length+z.width);
return z;
}
rectangle rec3(){
rectangle x;
cout<<"\narea is: "<<x.area<<endl<<"perimeter is: "<<x.perimeter<<endl;
return x;
}
You need to add methods to your rectangle struct.
struct rectangle
{
float length, width, area, perimeter;
void Input()
{
cout << "insert the length: ";
cin >> length;
cout << "\ninsert width: ";
cin>> width;
}
void Process(); // etc
void Output(); // etc
};
// Create a rectangle object and call it's methods
int main()
{
rectangle r;
r.Input();
r.Process();
r.Output()
}
The methods can now reference the member variables of the struct.
I suggest you change your design.
Place the input, process and output functions as methods inside the rectangle structure.
Placing the functions inside the structure allows them to access the data members.
Every time you return a new rectangle and assign it to your f variable, you are overwriting all of f's members, not just the ones you modified inside the function. You need to change the functions to modify f directly instead. You don't have to use a pointer for that, you can use a reference instead:
struct rectangle {
float length;
float width;
float area, perimeter;
};
void rec1(rectangle&);
void rec2(rectangle&);
void rec3(rectangle&);
int main(){
rectangle f;
rec1(f);
rec2(f);
rec3(f);
return 0;
}
void rec1(rectangle &r){
cout << "insert the length: ";
cin >> r.length;
cout << endl << "insert width: ";
cin >> r.width;
}
void rec2(rectangle &r){
r.area = r.length * r.width;
r.perimeter = 2 * (r.length + r.width);
}
void rec3(rectangle &r){
cout << endl << "area is: " << r.area << endl << "perimeter is: " << r.perimeter << endl;
}
But, this is C++ we are talking about, afterall. Member methods are your friends :)
struct rectangle {
float length;
float width;
float area, perimeter;
void rec1();
void rec2();
void rec3();
};
void rectangle::rec1(){
cout << "insert the length: ";
cin >> length;
cout << endl << "insert width: ";
cin >> width;
}
void rectangle::rec2(){
area = length * width;
perimeter = 2 * (length + width);
}
void rectangle::rec3(){
cout << endl << "area is: " << area << endl << "perimeter is: " << perimeter << endl;
}
int main(){
rectangle f;
f.rec1();
f.rec2();
f.rec3();
return 0;
}

need help fixing minor issues in my program [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
So here is my code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Point
{
private:
double px;
double py;
public:
void setX(const double x);
void setY(const double y);
double getX() const;
double getY() const;
};
class Rectangle
{
private:
string name;
Point blPoint;
double length, height;
public:
// member functions
void setName(const string & inName);
void setBottomLeft(const double x, const double y);
void setDimensions(const double inLength, const double inHeight);
string getName() const;
Point getBottomLeft() const;
double getLength() const;
double getHeight() const;
double area() const;
double perimeter() const;
Point midPoint() const;
void scaleBy2();
void display() const;
};
// FUNCTION PROTOTYPES GO HERE:
void welcome();
bool read_rec(const string promptName, const string errorInvalid, const string errorUsed, string & inName, vector<Rectangle> & list);
void read_coord(const string promptPoint, double & x, double & y);
void read_length(const string promptLength, double & inLength, double & inHeight);
void add_rec(const string Name, double x, double y, double inLength, double inHeight, vector<Rectangle> & list);
int main()
{
// Define your local variables, e.g. a vector of class Rectangle
Rectangle rec;
vector<Rectangle> list;
string prompt1stName = "Enter the name of the first rectangle: ";
string promptName = "Enter the name of the next rectangle: ";
string errorInvalid = "Invalid input. Type 'rec' following by the name or 'stop' if done.";
string errorUsed = "This name is already being used!";
string inName;
string Name;
// Display welcome banner
welcome();
/* Prompt user for first rectangle or 'stop' */
bool read = read_rec(prompt1stName, errorInvalid, errorUsed, inName, list);
// WHILE user input is invalid
while (read == false)
{
// Display "Try again! "
cout << "Try again! " << endl;
read = read_rec(prompt1stName, errorInvalid, errorUsed, inName, list);
}
// IF user input is not 'stop'
if (inName != "stop")
{
// Extract rectangle name from user input
int a = inName.length() - 4;
Name = inName.substr(4, a);
// Prompt for bottom left point
double x, y;
string promptPoint = "Enter " + Name + "'s bottom left x and y coords: ";
read_coord(promptPoint, x, y);
// Prompt for length and height
double inLength, inHeight;
string promptLength = "Enter " + Name + "'s length and height: ";
read_length(promptLength, inLength, inHeight);
// Add rectangle to the rectangle list
add_rec(Name, x, y, inLength, inHeight, list);
}
/* Prompt user for next rectangle or 'stop' */
// WHILE user input not 'stop'
while (inName != "stop")
{
// Display "Thank you! "
cout << "Thank you! ";
bool read = read_rec(promptName, errorInvalid, errorUsed, inName, list);
// WHILE user input is invalid while (read == false)
{
// Display "Try again! "
cout << "Try again! " << endl;
read = read_rec(promptName, errorInvalid, errorUsed, inName, list);
}
// IF user input is not 'stop'
if (inName != "stop")
{
// Extract rectangle name from user input
int a = inName.length() - 4;
Name = inName.substr(4, a);
// Prompt for bottom left point
double x, y;
string promptPoint = "Enter " + Name + "'s bottom left x and y coords: ";
read_coord(promptPoint, x, y);
// Prompt for length and height
double inLength, inHeight;
string promptLength = "Enter " + Name + "'s length and height: ";
read_length(promptLength, inLength, inHeight);
// Add rectangle to the rectangle list
add_rec(Name, x, y, inLength, inHeight, list);
}
}
// IF the rectangle list is not empty
if (list.size() != 0)
{
// Display all rectangles in the rectangle list
int rec_num = 0;
int i = 1;
while (i< list.size())
{
rec_num++;
i++;
}
cout << "You have " << rec_num+1 << " rectangle(s) in your list: ";
cout << endl;
for (int i = 0; i < list.size(); i++)
{
cout << "Rectangle '" << list[i].getName() << "' : ";
list[i].display();
list[i].scaleBy2();
cout << " After scale by 2: ";
list[i].display();
cout << endl;
}
}
// ELSE
else
{
// Display that no rectangles are in the list
cout << "You have no rectangles in your list." << endl;
}
return 0;
}
// FUNCTION DEFINITIONS GO HERE:
void welcome()
{
cout << "Welcome! Create your own list of rectangles." << endl;
cout << "You will be asked to provide information about each rectangle in your list by name." << endl;
cout << "Type the word 'stop' for the rectangle name when you are done." << endl;
cout << endl;
}
bool read_rec(const string promptName, const string errorInvalid, const string errorUsed, string & inName, vector<Rectangle> & list)
{
cout << promptName;
getline(cin, inName);
if (inName == "stop")
{
return(true);
}
else if (inName.substr(0,4) != "rec ")
{
cout << errorInvalid;
return(false);
}
else
{
int j = 0;
for (int i = 0; i < list.size(); i++)
{
if (inName == "rec " + list[i].getName())
{
j = j+1;
}
}
if (j == 0)
{
return(true);
}
if (j != 0)
{
cout << errorUsed;
return(false);
}
}
}
void read_coord(const string promptPoint, double & x, double & y)
{
cout << promptPoint;
cin >> x;
cin >> y;
}
void read_length(const string promptLength, double & inLength, double & inHeight)
{
cout << promptLength;
cin >> inLength;
cin >> inHeight;
cout << endl;
while (inLength <= 0 || inHeight <= 0)
{
cout << "Make length and height positive values. Try again.";
cout << promptLength;
cin >> inLength;
cin >> inHeight;
cout << endl;
}
}
void add_rec(const string Name, double x, double y, double inLength, double inHeight, vector<Rectangle> & list)
{
Rectangle rec;
rec.setName(Name);
rec.setBottomLeft(x, y);
rec.setDimensions(inLength, inHeight);
list.push_back(rec);
}
// CLASS MEMBER FUNCTION DEFINITINOS GO HERE:
void Point::setX(const double x)
{
px = x;
}
void Point::setY(const double y)
{
py = y;
}
double Point::getX() const
{
return (px);
}
double Point::getY() const
{
return (py);
}
void Rectangle::setName(const string & inName)
{
name = inName;
}
void Rectangle::setBottomLeft(const double x, const double y)
{
blPoint.setX(x);
blPoint.setY(y);
}
void Rectangle::setDimensions(const double inLength, const double inHeight)
{
length = inLength;
height = inHeight;
}
string Rectangle::getName() const
{
return (name);
}
Point Rectangle::getBottomLeft() const
{
return (blPoint);
}
double Rectangle::getLength() const
{
return (length);
}
double Rectangle::getHeight() const
{
return (height);
}
double Rectangle::area() const
{
// area = length * height
return(length * height);
}
double Rectangle::perimeter() const
{
// perimeter = 2 * (length + height);
return(2 * (length + height));
}
Point Rectangle::midPoint() const
{
Point midPoint;
double mx = blPoint.getX() + 0.5 * length;
double my = blPoint.getY() + 0.5 * height;
midPoint.setX(mx);
midPoint.setY(my);
return(midPoint);
}
void Rectangle::scaleBy2()
{
double midx = blPoint.getX() + 0.5 * length;
double midy = blPoint.getY() + 0.5 * height;
double newblPx = midx - length;
double newblPy = midy - height;
length = 2*length;
height = 2*height;
blPoint.setX(newblPx);
blPoint.setY(newblPy);
}
void Rectangle::display() const
{
cout << " Location is (" << blPoint.getX() << ", " << blPoint.getY() << "), length is " << length << ", height is " << height << "; Area is " << area() << "; perimeter is " << perimeter() << ", midpoint is located at (" << midPoint().getX() << ", " << midPoint().getY() << ")" << endl;
}
The only problem's I now have with the program is that it always outputs "Invalid input. Type 'rec' following by the name or 'stop' if done.", and i do not know how to change this. And when you put in a duplicate answer as in rec fire and rec fire, it will say that rec fire is already being used and then continue to prompt for that rectangle instead of asking for another name. ANY HELP would be much appreciated!!
This is wrong
/* Prompt user for first rectangle or 'stop' */
bool read = read_rec(prompt1stName, errorInvalid, errorUsed, inName, list);
// WHILE user input is invalid
while (read == false)
{
// Display "Try again! "
cout << "Try again! " << endl;
bool read = read_rec(prompt1stName, errorInvalid, errorUsed, inName, list);
}
You have two read variables, the read variable in the while condition is referring to the read variable declared first, the read variable declared second is never used. What you want is this
/* Prompt user for first rectangle or 'stop' */
bool read = read_rec(prompt1stName, errorInvalid, errorUsed, inName, list);
// WHILE user input is invalid
while (read == false)
{
// Display "Try again! "
cout << "Try again! " << endl;
read = read_rec(prompt1stName, errorInvalid, errorUsed, inName, list);
}
Now you have only one read variable. This accounts for the second error you describe I think.
Another way of coding this is like this
for (;;)
{
bool read = read_rec(prompt1stName, errorInvalid, errorUsed, inName, list);
if (read)
break;
cout << "Try again! " << endl;
}
In my view this kind of loop is better because it doesn't have the duplicated call to read_rec, so with this style of loop the mistake you made is impossible.