voids not being read - c++

I'm working on an Arena-ish console game. I want it so that I can have a void to make you fight certain monsters, instead of having to the monster fight out every time. Here's my code:
#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fstream>
using namespace std;
char select;
int randnum;
int level=1;
int maxhp=10;
int hp=maxhp;
int mhp;
int exp;
int dmg;
int m_maxhp;
int req_exp=10;
int day;
char boot;
int a;
ifstream leveli;
ofstream levelo;
ifstream playerhpi;
ofstream playerhpo;
ifstream expi;
ofstream expo;
ifstream maxhpi;
ofstream maxhpo;
ifstream req_expi;
ofstream req_expo;
ifstream dayi;
ofstream dayo;
void wait( time_t delay )
{
time_t timer0, timer1;
time( &timer0 );
do {
time( &timer1 );
} while (( timer1 - timer0 ) < delay );
}
// This is the void that's not being called
void bat()
{
m_maxhp=10;
mhp=m_maxhp;
do{
dmg= rand() % 4 + 1;
cout << "Batt attacks you for " << dmg;
hp=hp-dmg;
cout << ", leaving you with [" << hp << "/" << maxhp << "]" << endl;
wait(1);
if(hp<=0)
{
cout << "You've lose. Try harder next time.";
exp=exp/2;
day=day+1;
dayo.open("daynumber.dat");
dayo << day;
dayo.close();
}
else if(mhp<=0)
{
cout << "You have killed the Bat. You gain 6 EXP." << endl;
exp=exp+6;
day=day+1;
dayo.open("daynumber.dat");
dayo << day;
dayo.close();
expo.open("experience.dat");
expo << exp;
expo.close();
}
}while(mhp>0);
}
int main()
{
leveli.open("level.dat");
leveli >> level;
leveli.close();
playerhpi.open("health.dat");
playerhpi >> hp;
playerhpi.close();
expi.open("experience.dat");
expi >> exp;
expi.close();
maxhpi.open("maxhealth.dat");
maxhpi >> maxhp;
maxhpi.close();
req_expi.open("req_exp.dat");
req_expi >> req_exp;
req_expi.close();
cout << "Data successfully loaded. Start the game now? y/n" << endl;
boot=_getch();
if(boot=='n')
{
cout << "Exiting..." << endl;
wait(3);
exit(0);
}
else if(boot=='y'){
do{
if (exp==req_exp)
{
level=level+1;
cout << "Level Up! You are now level " << level << "!" << endl;
exp=0;
req_exp=req_exp*1.5;
req_expo.open("req_exp.dat");
req_expo << req_exp;
req_expo.close();
levelo.open("level.dat");
levelo << level;
levelo.close();
}
else{
cout << endl << "Day " << day << " in The Arena." << endl << "1. Fight" << endl << "2. Stats" << endl << "3. Full Heal" << endl << "4. Half Heal" << endl;
select=_getch();
if(select=='1')
{
srand((unsigned)time(0));
randnum = rand() % 500 + 1;
// cout << "*DEBUG* " << randnum << endl;
// This part doesn't work
if(randnum<300 && level<4)
{
cout << "You've been chosen to fight a Bat!" << endl;
wait(1.5);
void bat();
}
else
{
}
}
else if(select=='2')
{
cout << endl << "Health: [" << hp << "/" << maxhp << "]" << endl << "Level: [" << level << "]" << endl << "Experience: " << "[" << exp << "/" << req_exp << "]" << endl;
wait(0.5);
}
else
{
cout << "Invalid Command";
}
}
}while (boot=='y');
}
return 0;
}
Am I using voids incorrectly? If so, could someone point out what I should change?

if(randnum<300 && level<4)
{
cout << "You've been chosen to fight a Bat!" << endl;
wait(1.5);
void bat(); // ?
}
What is expected behavior here? void bat(); is a function declaration. This just introduces the name bat and does nothing else. It doesn't call a function named bat. In case you need just to call bat, you should write:
bat(); // a call to "bat"

When you call the function, you omit the return type, e.g. your code:
// This part doesn't work
if(randnum<300 && level<4)
{
cout << "You've been chosen to fight a Bat!" << endl;
wait(1.5);
void bat();
...
Should read:
// This part doesn't work
if(randnum<300 && level<4)
{
cout << "You've been chosen to fight a Bat!" << endl;
wait(1.5);
bat();
...

Related

memory leaks in c++

#pragma once
#ifndef SDDS_GIFT_H
#define SDDS_GIFT_H
#include <iostream>
namespace sdds
{
const int MAX_DESC = 15;
const double MAX_PRICE = 999.999;
const int MAX_WRAP = 20;
struct Gift
{
char m_description[MAX_DESC];
double m_price;
int m_units;
int m_wrapLayers;
struct Wrapping* m_wrap;
};
struct Wrapping
{
char* m_pattern;
};
void gifting(char*);
void gifting(double&);
void gifting(int&);
bool wrap(Gift& theGift);
bool unwrap(Gift& theGift);
void gifting(Gift& theGift);
void display(const Gift& theGift);
}
#endif
<pre><code>
#include <iostream>
#include "Gift.h"
using namespace std;
namespace sdds
{
void gifting(char* m_description) // sending info
{
cout << "Enter gift description: ";
cin.width(MAX_DESC + 1);
cin >> m_description;
}
void gifting(double& m_price)
{
cout << "Enter gift price: ";
cin >> m_price;
while (m_price > MAX_PRICE || m_price < 0)
{
cout << "Gift price must be between 0 and " << MAX_PRICE << std::endl;
cout << "Enter gift price: ";
cin >> m_price;
}
}
void gifting(int& m_units)// gifting function
{
cout << "Enter gift units: ";
cin >> m_units;
while (m_units < 1)
{
cout << "Gift units must be at least 1" << std::endl;
cout << "Enter gift units: ";
cin >> m_units;
};
}
bool wrap(Gift& m_wrap) {
if (m_wrap.m_wrapLayers > 0) {
cout << "Gift is already wrapped!" << endl;
return false;
}
else {
cout << "Wrapping gifts..." << endl;
cout << "Enter the number of wrapping layers for the Gift: ";
cin >> m_wrap.m_wrapLayers;
while (m_wrap.m_wrapLayers < 1) {
cout << "Layers at minimum must be 1, try again." << endl;
cout << "Enter the number of wrapping layers for the Gift: ";
cin >> m_wrap.m_wrapLayers;
}
int i = 0;
m_wrap.m_wrap = new Wrapping[MAX_WRAP + 1];
for (i = 0; i < m_wrap.m_wrapLayers; i++) {
m_wrap.m_wrap->m_pattern = new char[MAX_WRAP + 1];
cout << "Enter wrapping pattern #" << i + 1 << ": ";
cin >> m_wrap.m_wrap->m_pattern;
} // I put struct in a structure
return true;
}
delete[]m_wrap.m_wrap;
m_wrap.m_wrap = nullptr;
}
bool unwrap(Gift& g_unwrap) // unwrap function
{
if (g_unwrap.m_wrapLayers > 0) {
cout << "Gift being unwrapped." << endl;
g_unwrap.m_wrapLayers = 0;
g_unwrap.m_wrap->m_pattern = nullptr;
return true;
}
else
{
cout << "Gift isn't wrapped! Can't unwrap." << endl;
return false;
}
}
void display(const Gift& theGift)
{
cout << "Gift Details:" << endl;
cout << " Description: " << theGift.m_description << endl;
cout << " Price: " << theGift.m_price << endl;
cout << " Units: " << theGift.m_units << endl;
if (theGift.m_wrap == nullptr) // this part seems like a problem
{
cout << "Unwrapped" << endl;
}
else
{
int i = 0;
cout << "Wrap Layers: " << theGift.m_wrapLayers << endl;
for (i = 0; i < theGift.m_wrapLayers; i++) {
cout << "Wrap #" << i + 1 << ": " << theGift.m_wrap[i].m_pattern << endl;
}
}
}
void gifting(Gift& gift) //last function
{
cout << "Preparing a gift..." << endl;
gifting(gift.m_description);
gifting(gift.m_price);
gifting(gift.m_units);
wrap(gift);
}
}
</code></pre>
/***********************************************************************
// Workshop 2: Dynamic Memory & Function Overloading
// Version 2.0
// Date 2020/05/05
// Author Michael Huang
// Description
// Tests Gift module and provides a set of TODOs to complete
// which the main focuses are dynamic memory allocation
//
/////////////////////////////////////////////////////////////////
***********************************************************************/
#include <iostream>
#include "Gift.h"
#include "Gift.h" // intentional
using namespace std;
using namespace sdds;
void printHeader(const char* title)
{
char oldFill = cout.fill('-');
cout.width(40);
cout << "" << endl;
cout << "|> " << title << endl;
cout.fill('-');
cout.width(40);
cout << "" << endl;
cout.fill(oldFill);
}
<pre><code>
int main() {
Gift g1; // Unwrapped Gift
{
printHeader("T1: Checking Constants");
cout << "MAX_DESC: " << sdds::MAX_DESC << endl;
cout << "MAX_PRICE: " << sdds::MAX_PRICE << endl;
cout << "MAX_WRAP: " << sdds::MAX_WRAP << endl;
cout << endl;
}
{
printHeader("T2: Display Wrapped Gift");
gifting(g1.m_description);
gifting(g1.m_price);
gifting(g1.m_units);
cout << endl;
g1.m_wrap = nullptr;
g1.m_wrapLayers = 0;
display(g1);
cout << endl;
}
{
printHeader("T3: Wrap a gift");
if (wrap(g1))
cout << "Test succeeded!";
else
cout << "Test failed: wrapping didn't happen!" << endl;
cout << endl << endl;
}
{
printHeader("T4: Re-wrap a gift");
cout << "Attempting to rewrap the previous Gift: "
<< g1.m_description << endl;
if (wrap(g1) == false)
cout << "Test succeeded!";
else
cout << "Test failed: gift it's already wrapped, cannot wrap again!";
cout << endl << endl;
}
{
printHeader("T5: Unwrap a gift");
cout << "Attempting to unwrap the previous gift: "
<< g1.m_description << endl;
if (unwrap(g1))
cout << "Test succeeded!";
else
cout << "Test failed: you should be able to unwrap!";
cout << endl << endl;
}
{
printHeader("T6: Unwrap again");
cout << "Attempting to un-unwrap the previous gift: "
<< g1.m_description << endl;
if (!unwrap(g1))
cout << "Test succeeded!";
else
cout << "Test failed: you should not be able to unwrap again!";
cout << endl << endl;
}
Gift g2; // Unwrapped Gift
{
printHeader("T7: Prepare another gift");
g2.m_wrap = nullptr;
g2.m_wrapLayers = 0;
gifting(g2);
cout << endl;
display(g2);
cout << endl;
}
{
printHeader("T8: Unwrap the second gift");
unwrap(g2);
}
return 0;
}
Output matches perfectly but I don't know why memory leaks.. please help me. I am doubting my wrap part but I think there must be something else since deallocation seems fine.
I tried my best but I still cannot see which part is wrong.
I cannot see why my deallocation does not work I tried changing it so many times but nothing works.
On this line:
m_wrap.m_wrap->m_pattern = new char[MAX_WRAP + 1];
You allocate memory, but later you only:
delete[]m_wrap.m_wrap;
Also in your for loop you allocate memory, then get some input and store that inside the pointer, as a memory address. Should you ever dereference that, you will invoke undefined behavior, in practice that may likely will a segfault. You should consider rewriting at least that part from scratch.

While loop seems to be passing variables inversely from the Boolean condition

I've tested so many scenarios and it works without the while loop; but I just cant seem to figure out whats messing it up. if I pick an int in the target range 1-3 it passes and then freezes and i have to ctrl c the program out.
And if I pick a number outside that range it lets it pass in to the while loop and call the function. I'm very confused and this is the first program I've written with classes; so I feel like that probably is the issue.
Thanks.
#include <iostream>
using namespace std;
class Elevator
{
public:
void floorControl();
// Outputs floor actions and lets a user pick a floor number
int status();
// outputs floor positon
private:
int floorPosition = 1;
};
int main()
{
Elevator building[3];
int elevatorSelect;
cout << "\tElevator Status\n\tA\tB\tC\n"
<< "\t" << building[0].status() << "\t" << building[1].status()
<< "\t" << building[2].status() << endl
<< "\tWhich elevator do you want (1=A, 2=B, 3=C, or other to exit) ? ";
cin >> elevatorSelect;
cout << "\t" << elevatorSelect << endl;
while((elevatorSelect <= 3) && (elevatorSelect >=1));
{
building[elevatorSelect-1].floorControl();
cout << "\tElevator Status\n\tA\tB\tC\n"
<< "\t" << building[0].status() << "\t" << building[1].status()
<< "\t" << building[2].status() << endl
<< "\tWhich elevator do you want (1=A, 2=B, 3=C, or other to exit) ? ";
cin >> elevatorSelect;
cout << "\t" << elevatorSelect << endl;
}
return 0;
}
void Elevator::floorControl()
{
int floorSelect;
if(floorPosition > 1)
{
cout << "\tStarting at floor " << floorPosition << endl;
for(int i=1; i>floorPosition; floorPosition--)
cout << "\t Going down - now at floor " << floorPosition-1 << endl;
cout << "\tStopping at floor " << floorPosition << endl;
}
cout << "\tWhich floor do you want? ";
cin >> floorSelect;
if ((floorSelect < 1 )|| (floorSelect > 10))
cout << "\t**You pick up some dust off the wall; you missed**\n";
else
{
cout << "\tStarting at floor " << floorPosition << endl;
for (floorSelect; floorSelect > floorPosition; floorPosition++)
cout << "\t Going up - now at floor " << floorPosition+1 << endl;
cout << "\tStopping at floor " << floorPosition << endl;
}
}
int Elevator::status()
{
return floorPosition;
}

Error with pointer when using dynamic_cast to detect derived class

I'd like to have some help on an issue I face.
I made an inheritance with polymorph program with class Shape and Circle (derived from shape). So I have some code like this
main.cpp
Shape* shape = new (nothrow) Shape[size]();
input_circle(shape);
show_circle_area(shape);
and a procedure in main.cpp too
void show_circle_area(Shape *mshape){
int i;
sort(mshape,mshape+totshape,sortByArea);
cout << "CIRCLE" << endl;
for (i=0;i<totshape;i++)
if (dynamic_cast<Circle*> (mshape[i]))
cout << mshape[i].getWidth() << " " << mshape[i].getArea() << " " << mshape[i].getPerimeter() << endl;
}
when I run this program, I always got this error :
main2.cpp: In function 'void output_circle(Shape*)':
main2.cpp:66:39: error: cannot dynamic_cast '*(mshape + ((sizetype)(((unsigned int)i) * 40u)))' (of type 'class Shape') to type 'class Circle*' (source is not a pointer)
if (dynamic_cast<Circle*> (mshape[i]))
^
Anyone can help what should I do to fix this?
main.cpp (updated)
#include "Shape.h"
#include "Circle.h"
#include "Rectangle.h"
#include "Square.h"
#include <fstream>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <iomanip>
#include <limits>
#include <typeinfo>
using namespace std;
const int size = 200;
int totshape = 0;
// INPUT FROM FILE
void input_circle(Shape* mshape[]){
ifstream file;
int i;
double r;
file.open("circle.txt");
while (file >> r){
Circle* crl = new (nothrow) Circle(r);
mshape[totshape]=crl;
totshape++;
}
file.close();
}
void input_rectangle(Shape* mshape[]){
ifstream file;
int i;
double w,h;
file.open("rectangle.txt");
while (file >> w >> h){
Rectangle* rec = new (nothrow) Rectangle(w,h);
mshape[totshape]=rec;
totshape++;
}
file.close();
}
void input_square(Shape* mshape[]){
ifstream file;
int i;
double s;
file.open("square.txt");
while (file >> s){
Square* sqr = new (nothrow) Square(s);
mshape[totshape]=sqr;
totshape++;
}
file.close();
}
//OUTPUT TO FILE
void output_circle(Shape *mshape[]){
int i;
ofstream file;
file.open("outcircle.txt");
file << "radius\tarea\tperimeter" << endl;
for (i=0;i<totshape;i++){
if (dynamic_cast<Circle*> (mshape[i]))
file << mshape[i]->getWidth() << "\t" << mshape[i]->getArea() << "\t" << mshape[i]->getPerimeter() << endl;
}
file.close();
}
void output_rectangle(Shape *mshape[]){
int i;
ofstream file;
file.open("outrectangle.txt");
file << "width\theight\tarea\tperimeter" << endl;
for (i=0;i<totshape;i++){
if (dynamic_cast<Rectangle*> (mshape[i]))
file << mshape[i]->getWidth() << "\t" << mshape[i]->getHeight() << "\t" << mshape[i]->getArea() << "\t" << mshape[i]->getPerimeter() << endl;
}
file.close();
}
void output_square(Shape *mshape[]){
int i;
ofstream file;
file.open("outsquare.txt");
file << "sisi\tarea\tperimeter" << endl;
for (i=0;i<totshape;i++){
if (dynamic_cast<Square*> (mshape[i]))
file << mshape[i]->getWidth() << "\t" << mshape[i]->getArea() << "\t" << mshape[i]->getPerimeter() << endl;
}
file.close();
}
//SORTING STL FOR AREA AND PERIMETER
bool sortByArea(Shape lhs[], Shape rhs[]) {
return lhs->getArea() < rhs->getArea();
}
bool sortByPerimeter(Shape lhs[], Shape rhs[]){
return lhs->getArea() < rhs->getArea();
}
//SHOW DATA SORT BY AREA
void show_shape_area(Shape *shape[]){
int i;
sort(shape,shape+totshape,sortByArea);
cout << "ALL SHAPE" << endl;
for (i=0;i<totshape;i++)
cout << shape[i]->getWidth() << " " << shape[i]->getWidth() << " " << shape[i]->getArea() << " " << shape[i]->getPerimeter() << endl;
}
void show_circle_area(Shape *mshape[]){
int i;
sort(mshape,mshape+totshape,sortByArea);
cout << "CIRCLE" << endl;
for (i=0;i<totshape;i++)
if (dynamic_cast<Circle*> (mshape[i]))
cout << mshape[i]->getWidth() << " " << mshape[i]->getArea() << " " << mshape[i]->getPerimeter() << endl;
}
void show_rectangle_area(Shape *mshape[]){
int i;
sort(mshape,mshape+totshape,sortByArea);
cout << "RECTANGLE" << endl;
for (i=0;i<totshape;i++)
if (dynamic_cast<Rectangle*> (mshape[i]))
cout << mshape[i]->getWidth() << " " << mshape[i]->getHeight() << " " << mshape[i]->getArea() << " " << mshape[i]->getPerimeter() << endl;
}
void show_square_area(Shape *mshape[]){
int i;
sort(mshape,mshape+totshape,sortByArea);
cout << "SQUARE" << endl;
for (i=0;i<totshape;i++)
if (dynamic_cast<Square*> (mshape[i]))
cout << mshape[i]->getWidth() << " " << mshape[i]->getArea() << " " << mshape[i]->getPerimeter() << endl;
}
//SHOW DATA SORT BY PERIMETER
void show_shape_perimeter(Shape *shape[]){
int i;
sort(shape,shape+totshape,sortByPerimeter);
cout << "ALL SHAPE" << endl;
for (i=0;i<totshape;i++)
cout << shape[i]->getWidth() << " " << shape[i]->getWidth() << " " << shape[i]->getArea() << " " << shape[i]->getPerimeter() << endl;
}
void show_circle_perimeter(Shape *mshape[]){
int i;
//Shape * tempshape;
sort(mshape,mshape+totshape,sortByPerimeter);
cout << "CIRCLE" << endl;
for (i=0;i<totshape;i++)
//cout << "masuk for" << endl;
//tempshape=&mshape[i];
if (dynamic_cast<Circle*> (mshape[i])){
cout << mshape[i]->getWidth() << " " << mshape[i]->getArea() << " " << mshape[i]->getPerimeter() << endl;
//cout << "masuk" << endl;
}
}
void show_rectangle_perimeter(Shape *mshape[]){
int i;
sort(mshape,mshape+totshape,sortByPerimeter);
cout << "RECTANGLE" << endl;
for (i=0;i<totshape;i++)
if (dynamic_cast<Rectangle*> (mshape[i]))
cout << mshape[i]->getWidth() << " " << mshape[i]->getHeight() << " " << mshape[i]->getArea() << " " << mshape[i]->getPerimeter() << endl;
}
void show_square_perimeter(Shape *mshape[]){
int i;
sort(mshape,mshape+totshape,sortByPerimeter);
cout << "SQUARE" << endl;
for (i=0;i<totshape;i++)
if (dynamic_cast<Square*> (mshape[i]))
cout << mshape[i]->getWidth() << " " << mshape[i]->getArea() << " " << mshape[i]->getPerimeter() << endl;
}
//ADD DATA
void add_circle(Shape *mshape[]){
int input;
cout << endl << "Masukkan jari-jari : ";
while (!(cin >> input) || input < 0) // <<< note use of "short circuit" logical operation here
{
cout << "Input tidak valid" << endl;
cout << "Masukkan jari-jari : ";
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // NB: preferred method for flushing cin
}
Circle* crl = new (nothrow) Circle(input);
mshape[totshape]=crl;
totshape++;
}
void add_rectangle(Shape *mshape[]){
int inwidth, inheight;
cout << endl << "Masukkan panjang : ";
while (!(cin >> inwidth) || inwidth < 0) // <<< note use of "short circuit" logical operation here
{
cout << "Input tidak valid" << endl;
cout << "Masukkan panjang : ";
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // NB: preferred method for flushing cin
}
cout << endl << "Masukkan lebar : ";
while (!(cin >> inheight) || inheight < 0 || !(inheight < inwidth)) // <<< note use of "short circuit" logical operation here
{
cout << "Input tidak valid" << endl;
cout << "Masukkan lebar : ";
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // NB: preferred method for flushing cin
}
Rectangle* rec = new (nothrow) Rectangle(inwidth,inheight);
mshape[totshape]=rec;
totshape++;
}
void add_square(Shape *mshape[]){
int input;
cout << endl << "Masukkan sisi : ";
while (!(cin >> input) || input < 0) // <<< note use of "short circuit" logical operation here
{
cout << "Input tidak valid" << endl;
cout << "Masukkan sisi : ";
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // NB: preferred method for flushing cin
}
Square* sqr = new (nothrow) Square(input);
mshape[totshape]=sqr;
totshape++;
}
//DELETE DATA
//MAIN PROGRAM
int main(){
Shape* shape[size];
input_circle(shape);
input_rectangle(shape);
input_square(shape);
show_shape_area(shape);
show_shape_perimeter(shape);
show_circle_area(shape);
show_circle_perimeter(shape);
show_rectangle_area(shape);
show_rectangle_perimeter(shape);
show_square_area(shape);
show_square_perimeter(shape);
//add_circle(shape);
//show_circle_area(shape);
//add_rectangle(shape);
//show_rectangle_area(shape);
//add_square(shape);
//show_square_area(shape);
output_circle(shape);
output_rectangle(shape);
output_square(shape);
return 0;
}
Your problem is here:
mshape[totshape]=crl;
This assignment just copies the "Shape part" inside crl to mshape[totshape] thus mshape[totshape] is still a shape, not a circle.
In order to fix your problem, please use an array of Shape* pointers instead of Shape values:
Shape* shape[size]; // we should write this as size is a const
And, your input_***() functions:
void input_circle(Shape* mshape[]){
ifstream file;
int i;
double r;
file.open("circle.txt");
while (file >> r){
Circle* crl = new Circle(r);
mshape[totshape]=crl;
totshape++;
}
file.close();
}
Note that the function prototype is changed, please do it for other functions, and use mshape[i]->foo instead of mshape[i].foo
The casting now is: if (dynamic_cast<Circle*> (mshape[i])){
Don't forget to free memory before ending since we are using pointers:
for (int i = 0; i < totshape; i++) delete mshape[i];
This deleting would force you to make Shape's destructor be virtual:
class Shape {
public:
virtual ~Shape() {...}
}
Otherwise, Circle, Rectangle ... 's destructors will not be called.

Why Do I have an '=' sign output and 2 smiley faces instead of the correct output? C++

this is an update to show chages, details below.
here is a link to snap shot of output
https://dl.dropboxusercontent.com/u/34875891/wrongoutput.PNG
#include <iostream>
#include <iomanip>
#include <string>
#include <cstring>
using namespace std;
//create HotelRoom class
class HotelRoom
{
private:
char* ptr_guest;
char room_number[3];
int room_capacity;
int occupancy_status;
double daily_rate;
public:
HotelRoom(char roomNumber[], int roomCapacity, double roomRate, char* ptr_name, int occupancyStatus);
~HotelRoom();
void Display_Number();
void Display_Guest();
int Get_Capacity();
int Get_Status();
double Get_Rate();
int Change_Status(int);
double Change_Rate(double);
};
HotelRoom::HotelRoom(char roomNumber[], int roomCapacity, double roomRate, char* ptr_name, int occupancyStatus)
{
strcpy(room_number, roomNumber);
room_capacity = roomCapacity;
daily_rate = roomRate;
ptr_guest = new char[strlen(ptr_name) + 1];
strcpy(ptr_guest, ptr_name);
occupancy_status = occupancyStatus;
}
HotelRoom::~HotelRoom()
{
cout << endl;
cout << "Destructor Executed";
cout << endl;
delete [] ptr_guest;
}
void HotelRoom::Display_Guest()
{
char* temp = ptr_guest;
while(*temp != '\0')
cout << *temp++;
}
void HotelRoom::Display_Number()
{
cout << room_number;
}
int HotelRoom::Get_Capacity()
{
return room_capacity;
}
int HotelRoom::Get_Status()
{
return occupancy_status;
}
double HotelRoom::Get_Rate()
{
return daily_rate;
}
int HotelRoom::Change_Status(int roomStatus)
{
if(roomStatus <= room_capacity )
{
occupancy_status = roomStatus;
return occupancy_status;
}
else
occupancy_status = -1;
}
double HotelRoom::Change_Rate(double newRate)
{
daily_rate = newRate;
return daily_rate;
}
int main()
{
cout << setprecision(2)
<< setiosflags(ios::fixed)
<< setiosflags(ios::showpoint);
//Declare variables to hold data
char roomNumber[3] = {'1','3','\0'};
char guestName[20];
double roomRate = 89.00;
int roomCapacity = 4;
int occupancyStatus = 0;
int status;
int checkOut;
int newCustomer;
//Ask for user input
cout << "What is the guest's name: ";
cin.getline(guestName, 20);
cout << endl;
cout << "How many guests will be staying in the room: ";
cin >> status;
HotelRoom HotelRoom1(roomNumber, roomCapacity, roomRate, guestName, status);
//Display Rooom information
cout << endl;
cout << endl;
if(HotelRoom1.Change_Status(status))
{
cout << endl;
cout << "Guest's Name: ";
HotelRoom1.Display_Guest();
cout << endl;
cout << endl;
cout << "The capacity of this room is " << HotelRoom1.Get_Capacity() << endl;
cout << endl;
cout << "There are " << HotelRoom1.Get_Status() << " guests staying in the room";
}
cout << endl;
cout << endl;
cout << "Your room number is " << HotelRoom1.Display_Number();
cout << endl;
cout << endl;
cout << "The rate for this room is " << HotelRoom1.Get_Rate();
cout << endl;
cout << endl;
//chech this guest out?
cout << "Check this guest out? ('1 = yes' '0' = no) ";
cin >> checkOut;
switch(checkOut)
{
case 1:
HotelRoom1.Change_Status(0);
for(int i = 0; i < 3; ++i )
{
cout << endl;
}
cout << "You have checked out of room number " << HotelRoom1.Display_Number();
cout << endl;
cout << endl;
cout << "The capacity of this room is " << HotelRoom1.Get_Capacity();
cout << endl;
cout << endl;
cout << "There are currently " << HotelRoom1.Get_Status() << " occupants";
cout << endl;
cout << endl;
cout << "The rate of this room was " << HotelRoom1.Get_Rate();
break;
}
//check in new guest?
cout << endl;
cout << endl;
cout << "Check in new guest? ('1 = yes' '0' = no) ";
cin >> newCustomer;
for(int i = 0; i < 3; ++i )
{
cout << endl;
}
switch (newCustomer)
{
case 1:
HotelRoom HotelRoom2(roomNumber, roomCapacity, roomRate, guestName, status);
HotelRoom1.Change_Rate(175.00); //Change rate of room
cout << endl;
cout << "What is the guest's name: ";
cin.getline(guestName, 20);
cout << endl;
cout << "How many guests will be staying in the room: ";
cin >> status;
cout << endl;
cout << endl;
//Display new guest information
if(HotelRoom1.Change_Status(status))
{
cout << endl;
cout << endl;
cout << "The capacity of this room is " << HotelRoom1.Get_Capacity() << endl;
cout << endl;
cout << "There are " << HotelRoom1.Get_Status() << " guests staying in the room";
}
cout << endl;
cout << endl;
cout << "Your room number is " << HotelRoom1.Display_Number();
cout << endl;
cout << endl;
cout << "The rate for this room is " << HotelRoom1.Get_Rate();
cout << endl;
cout << endl;
break;
}
cout << endl;
system("PAUSE");
return 0;
}
this is an update to show chages, details below.
here is a link to snap shot of output
https://dl.dropboxusercontent.com/u/34875891/wrongoutput.PNG
char HotelRoom::Display_Guest()
{
cout << ptr_guest;
}
string HotelRoom::Display_Number()
{
cout << room_number;
}
int HotelRoom::Change_Status(int roomStatus)
{
if(roomStatus <= room_capacity )
{
occupancy_status = roomStatus;
return occupancy_status;
}
else
occupancy_status = -1;
}
These functions claim to be returning values. The first two are not, the last is not under certain conditons. Calling the first two is undefined behavior. Calling Change_Status with roomStatus > room_capacity is also undefined behavior.
There may be other problems with the code, but the elephant in the room is the undefined behavior. Any other debugging while you have undefined behavior is theoretically a waste of time.

Addressbook writing to file

I have an Addressbook C++ program that compiles and everything, but I cannot figure out how to write it to a file that saves the data each time it exits. Here is my code:
//AddressBook Program
#include <iostream>
#include <string.h>
#include <cstdlib>
#include <stdio.h>
using namespace std;
class AddressBook{
public :
AddressBook()
{
count = 0;
}
void AddEntry();
void DisplayAll();
void DisplayEntry(int i); // Displays one entry
void SearchEntry();
int MainMenu();
struct Entry_Struct
{
char firstName[ 15 ] ;
char lastName[ 15 ] ;
char birthday[ 15 ] ;
char phone[ 15 ] ;
char email[ 15 ] ;
};
Entry_Struct entries[100];
unsigned int count;
};
void AddressBook::AddEntry()
{
cout << "Entry number " << (count + 1) << " : " << endl;
cout << "Enter First Name: ";
cin >> entries[count].firstName;
cout << "Enter Last Name: ";
cin >> entries[count].lastName;
cout << "Enter Date of Birth: ";
cin >> entries[count].birthday;
cout << "Enter Phone Number: ";
cin >> entries[count].phone;
cout << "Enter Email: ";
cin >> entries[count].email;
++count; // tally total entry count
}
void AddressBook::DisplayEntry(int i)
{
cout << "Entry[" << i + 1 << "] : " << endl; // states # of entry
cout << "First name : " << entries[i].firstName << endl;
cout << "Last name : " << entries[i].lastName << endl;
cout << "Date of birth : " << entries[i].birthday << endl;
cout << "Phone number : " << entries[i].phone << endl;
cout << "Email: " << entries[i].email << endl;
}
void AddressBook::DisplayAll()
{
cout << "Number of entries : " << count << endl;
for(int i = 0;i < count;++i)
DisplayEntry(i);
}
void AddressBook::SearchEntry()
{
char lastname[32];
cout << "Enter last name : ";
cin >> lastname;
for(int i = 0;i < count;++i)
{
if(strcmp(lastname, entries[i].lastName) == 0)
{
cout << "Found ";
DisplayEntry(i);
cout << endl;
}
}
}
// Your class
AddressBook my_book;
int MainMenu()
{
int num;
bool bQuit = false;
// Put all your code into a while loop.
while(bQuit == false)
{
cout << "+-------------------------------------+" << endl;
cout << "| Address Book Menu |" << endl;
cout << "| |" << endl;
cout << "| 1- Add an entry |" << endl;
cout << "| 2- Search for an entry by last name |" << endl;
cout << "| 3- Display all entries |" << endl;
cout << "| 4- Exit |" << endl;
cout << "| |" << endl;
cout << "+-------------------------------------+" << endl;
cout << endl;
cout << "Please enter a number for one of the above options: ";
cin >> num;
cout << endl;
if (num == 1)
my_book.AddEntry();
else if (num == 2)
my_book.SearchEntry();
else if (num == 3)
my_book.DisplayAll();
else if (num == 4)
bQuit = true;
else
cout << "Invalid choice. Please try again" << endl;
cout << endl;
}
return 0;
}
int main (){
MainMenu();
return 0;
}
I've gone over my textbook all day and nothing I'm doing is working.
Here is a basic example of opening, and writing an output file,
// basic file operations
#include <iostream>
#include <fstream>
using namespace std;
int main () {
ofstream outfile;
outfile.open ("addressbook.txt");
outfile << "Daffy,Duck,123 Main Street,Anytown,OH,USA,123-456-7890\n";
myfile.close();
return 0;
}
You need to have an inserter for your class. It's done using operator <<:
// Inside your class:
friend std::istream& operator<<(std::ostream& os, const AddressBook ab)
{
return os << /* ... */
}
As you can see, a user-defined operator << can be implemented in terms of the pre-defined standard inserter. You can use it in the following way:
std::ifstream in("yourtxtfile.txt");
in << my_book;