Operator overloading += to add new object - c++

Learning operator overloading in this project, and below in the ship.cpp file is where I think my error is.
This is the test file, I cannot change this:
#include <iostream>
#include "Ship.h"
#include "Ship.h"
#include "Engine.h"
#include "Engine.h"
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);
}
int main()
{
{
printHeader("T1: Testing Constants");
cout << "TYPE_MAX_SIZE: " << sdds::TYPE_MAX_SIZE << endl;
cout << "MIN_STD_POWER: " << sdds::MIN_STD_POWER << endl;
cout << "MAX_STD_POWER: " << sdds::MAX_STD_POWER << endl;
cout << endl;
}
{
printHeader("T2: Testing Default Constructor");
Ship invalid;
invalid.display();
invalid += Engine("D2", 2.1);
cout << endl;
}
Engine engines[] = {
Engine("V8", 4.4),
Engine("V8", 5.0),
Engine("Inline", 4.1),
Engine("D3", 7.0),
Engine("D0", 2.0),
Engine("D1", 3.2),
};
{
printHeader("T3: Testing Custom Constructor");
Ship titanic("cruiser", engines, 6);
titanic.display();
cout << endl;
}
{
printHeader("T4: Testing Conversion to Bool Operator");
Ship invalid;
Ship titanic("liner", engines, 1);
if (invalid)
cout << "1. Test Failed! Object should be invalid.\n";
else
cout << "1. Test succeeded!\n";
if (titanic)
cout << "2. Test succeeded!\n";
else
cout << "3. Test Failed! Object should be valid.\n";
cout << endl;
}
{
printHeader("T5: Testing += and < Operators");
Ship titanic("liner", engines, 3);
char type[]{ "D0" };
while (titanic < sdds::MIN_STD_POWER)
{
type[1]++;
cout << "Ship not up to standard. Required power: "
<< sdds::MIN_STD_POWER << endl;
titanic += Engine(type, 2.1);
}
titanic.display();
if (sdds::MAX_STD_POWER < titanic)
cout << "Too much power." << endl;
else
cout << "Ship doesn't exceed power regulation of: "
<< sdds::MAX_STD_POWER << endl;
}
return 0;
}
This is my Ship.cpp file. My error is in the += operator function, where I have to add an engine but don't understand how I should approach it.
#include <iostream>
#include <cstring>
#include "Ship.h"
using namespace std;
namespace sdds {
Ship::Ship(){
m_type[0] = '\0';
m_engCnt = 0;
}
Ship::Ship(const char* type, const Engine engines[], int cnt){
if (type != nullptr && engines != nullptr && cnt > 0) {
// create a valid ship
strncpy(m_type, type, TYPE_MAX_SIZE);
for (int i = 0; i < cnt; i++) {
m_engines[i] = engines[i];
}
m_engCnt = cnt;
}else{
m_type[0] = '\0';
m_engCnt = 0;
}
}
Ship::operator bool() const {
// return true if the ship is valid (not empty)
if(m_type[0] == '\0' || m_engCnt == 0){
return false;
}else{
return true;
}
}
Ship& Ship::operator+=(Engine e){
if (!*this) {
cout << "The Object is not valid! Engine cannot be added!" << endl;
return *this;
}else if (m_engCnt == NUM_OF_ENGINES){
return *this;
}else{
// ERROR I BELIEVE IS HERE --> I dont understand the syntax to add engine here
m_engCnt++;
return *this;
}
}
double Ship::calculatePower() const {
double power = 0;
for (int i = 0; i < m_engCnt; i++) {
power += m_engines[i].get() * 5;
}
return power;
}
void Ship::display()const{
if (*this) {
cout << m_type << " - " << calculatePower() << endl;
Engine e;
for (int i = 0; i < m_engCnt; i++) {
m_engines[i].display();
}
}else{
cout << "No available data" << endl;
}
}
bool Ship::operator<(double power) const{
if (calculatePower() < power) {
return true;
}else{
return false;
}
}
bool operator<(double power, const Ship& theShip){
if (power < theShip.calculatePower()) {
return true;
}else{
return false;
}
}
}
This is my engine.cpp file:
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <string.h>
#include "Engine.h"
using namespace sdds;
using namespace std;
namespace sdds {
Engine::Engine(){
m_type[0] = '\0';
m_size = 0.0;
}
Engine::Engine(const char* type, double size){
strncpy(m_type, type, TYPE_MAX_SIZE);
m_size = size;
}
double Engine::get() const{
return m_size;
}
void Engine::display() const{
cout << m_size << " liters - " << m_type << endl;
}
}
This should be the output, but my function is stuck in the while loop:
|> T5: Testing += and < Operators
----------------------------------------
Ship not up to standard. Required power: 90.111
Ship not up to standard. Required power: 90.111
Ship not up to standard. Required power: 90.111
liner - 99
4.4 liters - V8
5 liters - V8
4.1 liters - Inline
2.1 liters - D1
2.1 liters - D2
2.1 liters - D3
Ship doesn't exceed power regulation of: 99.999

Your operator+= is not doing anything with the Engine that is passed to it. Your Ship class has an m_engines array, which your Ship constructor adds Engines to (without regard to NUM_OF_ENGINES, though), but your operator+= is not.
Your constructor and operator+= should look more like this instead:
Ship::Ship(const char* type, const Engine engines[], int cnt){
if (type != nullptr && engines != nullptr && cnt > 0) {
// create a valid ship
strncpy(m_type, type, TYPE_MAX_SIZE);
if (cnt > NUM_OF_ENGINES) cnt = NUM_OF_ENGINES; // <-- ADD THIS LINE!
for (int i = 0; i < cnt; ++i) {
m_engines[i] = engines[i];
}
m_engCnt = cnt;
}else{
m_type[0] = '\0';
m_engCnt = 0;
}
}
Ship& Ship::operator+=(Engine e){
if (!*this) {
cout << "The Object is not valid! Engine cannot be added!" << endl;
return *this;
}else if (m_engCnt == NUM_OF_ENGINES){
return *this;
}else{
m_engines[m_engCnt] = e; // <-- ADD THIS LINE!!!
m_engCnt++;
return *this;
}
}
I would suggest re-writing the constructor and operator+= to look more like this instead:
Ship::Ship(const char* type, const Engine engines[], int cnt){
strncpy(m_type, type != nullptr ? type : "", TYPE_MAX_SIZE);
if (engines != nullptr && cnt > 0) {
if (cnt > NUM_OF_ENGINES) cnt = NUM_OF_ENGINES;
for (int i = 0; i < cnt; ++i) {
m_engines[i] = engines[i];
}
m_engCnt = cnt;
}
else
m_engCnt = 0;
}
Ship& Ship::operator+=(const Engine &e){
if (m_type[0] != '\0' && m_engCnt < NUM_OF_ENGINES) {
m_engines[m_engCnt] = e;
++m_engCnt;
}
return *this;
}

Related

C++ Memory Leak Error (definitely lost: 280 bytes in 2 blocks)

I have Memory Leak in my code and not sure how to diagnose it. There are 3 files and the main.cpp is the test file therefore cannot be altered. The program is using a Mem Checker and it displays that ==159804== Memcheck, a memory error detector, definitely lost: 280 bytes in 2 blocks.
Main.cpp (Cannot be altered)
#include<iostream>
#include<cstring>
#include"Basket.h"
#include"Basket.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);
}
int main()
{
sdds::Fruit fruits[]{
{"apple", 0.65},
{"banana", 1.25},
{"pear", 0.50},
{"mango", 0.75},
{"plum", 2.00},
};
{
printHeader("T1: Default Constructor");
Basket aBasket;
cout << aBasket;
// conversion to bool operator
if (aBasket)
cout << "Test failed: the basket should be empty!\n";
else
cout << "Test succeeded: operator said the basket is empty!\n";
cout << endl;
}
{
printHeader("T2: Custom Constructor");
Basket aBasket(fruits, 2, 6.99);
cout << aBasket;
// conversion to bool operator
if (aBasket)
cout << "Test succeeded: operator said the basket has content!\n";
else
cout << "Test failed: the basket should NOT be empty!\n";
cout << endl;
}
{
printHeader("T3: += operator");
Basket aBasket;
aBasket += fruits[2];
(aBasket += fruits[0]) += fruits[4];
aBasket.setPrice(12.234);
cout << aBasket;
cout << endl;
}
{
printHeader("T4: Copy Constructor");
Basket b1;
Basket b2(b1);
cout << "Basket #1 -> " << b1;
cout << "Basket #2 -> " << b2;
b1 += fruits[3];
b1.setPrice(3.50);
Basket b3(b1);
cout << "Basket #3 -> " << b3;
cout << endl;
}
{
printHeader("T5: Copy Assignment");
Basket b1, b2, b3(fruits, 5, 19.95);
b1 = b2;
cout << "Basket #1 -> " << b1;
cout << "Basket #2 -> " << b2;
b1 = b3;
cout << "Basket #1 -> " << b1;
b3 = b2;
cout << "Basket #3 -> " << b3;
}
return 0;
}
Basket.h
#ifndef Basket_h
#define Basket_h
#include <stdio.h>
#include <iomanip>
#include <iostream>
namespace sdds{
struct Fruit
{
char m_name[30 + 1];
double m_qty;
};
class Basket{
private:
Fruit *m_fruits;
int m_cnt;
double m_price;
public:
Basket();
Basket(Fruit* fruits, int cnt, double price);
Basket(Basket &d);
Basket& operator = (Basket &d);
~Basket();
void setPrice(double price);
operator bool() const;
Basket& operator+=(Fruit d);
friend std::ostream& operator << (std::ostream& output, Basket test);
};
}
#endif /* Basket_h */
Basket.cpp
#include "Basket.h"
using namespace sdds;
namespace sdds {
Basket::Basket(){
m_fruits = nullptr;
m_cnt = 0;
m_price = 0;
}
Basket::Basket(Fruit* fruits, int cnt, double price){
if (cnt > 0 && fruits != nullptr) {
m_cnt = cnt;
m_price = price;
m_fruits = new Fruit[cnt + 1];
for (int i = 0; i < cnt; i++) {
m_fruits[i] = fruits[i];
}
}else{
m_fruits = nullptr;
m_cnt = 0;
m_price = 0;
}
}
Basket::Basket(Basket &d){
m_price = d.m_price; // Shallow Copying
m_cnt = d.m_cnt;
m_fruits = new Fruit[m_cnt + 1];
for (int i = 0; i < m_cnt; i++) { // Deep Copying
m_fruits[i] = d.m_fruits[i];
}
}
Basket& Basket::operator = (Basket &d){
m_price = d.m_price;
m_cnt = d.m_cnt;
m_fruits = new Fruit[m_cnt + 1];
for (int i = 0; i < m_cnt; i++) {
m_fruits[i] = d.m_fruits[i];
}
return *this;
}
Basket::~Basket(){
delete [] m_fruits;
}
void Basket::setPrice(double price){
m_price = price;
}
Basket::operator bool() const {
// returning true if the Basket is valid
return m_fruits != nullptr;
}
Basket& Basket::operator+=(Fruit d){
Fruit* tmp = new Fruit[m_cnt + 1];
for (int i = 0; i < m_cnt; i++) {
tmp[i] = m_fruits[i];
}
tmp[m_cnt++] = d;
delete [] m_fruits;
m_fruits = tmp;
return *this;
}
std::ostream& operator << (std::ostream& output, Basket test){
if (test.m_cnt == 0 || test.m_price == 0 || test.m_fruits == nullptr) {
output << "The basket is empty!" << std::endl;
}else{
output << "Basket Content:" << std::endl;
std::cout << std::fixed;
std::cout << std::setprecision(2);
for (int i = 0 ; i < test.m_cnt; i++) {
output << std::setw(10) << test.m_fruits[i].m_name << ": " <<test.m_fruits[i].m_qty << "kg" << std::endl;
}
output << "Price: " << test.m_price << std::endl;
}
return output;
}
}
Your assignment operator leaks memory, since you failed to delete[] the original data when doing the assignment.
The easiest way to get a working assignment operator is to use the copy/swap idiom:
#include <algorithm>
//...
Basket& Basket::operator = (const Basket &d)
{
if ( &d != this)
{
Basket temp(d);
std::swap(temp.m_price, m_price);
std::swap(temp.m_cnt, cnt);
std::swap(temp.m_fruits, fruits);
}
return *this;
}
Your original assignment operator had multiple flaws:
Did not delete[] the old memory.
Did not do a check for self-assignment, thus Basket a; a = a; would fail.
Changed member variables before issuing a call to new[], thus an exception thrown would corrupt your object.
All three issues are taken care of with the code shown above.
In fact, item 2) need not be done for copy / swap to work (but done in the example code above, just to show what your original code was missing).

C++ Buffer OverRun (Invalid read of size 8)

This is the main Test File and cannot be changed and there are 3 files in total not including Header files. main.cpp, engine.cpp, ship.cpp. I have included a screenshot of my error as well but its the invalid read of size 8 error (memory leak) at the T5 part of the test in the ship.cpp file. It outputs the correct answer but obviously has a memory leak.My error pic
#include <iostream>
#include "Ship.h"
#include "Ship.h"
#include "Engine.h"
#include "Engine.h"
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);
}
int main()
{
{
printHeader("T1: Testing Constants");
cout << "TYPE_MAX_SIZE: " << sdds::TYPE_MAX_SIZE << endl;
cout << "MIN_STD_POWER: " << sdds::MIN_STD_POWER << endl;
cout << "MAX_STD_POWER: " << sdds::MAX_STD_POWER << endl;
cout << endl;
}
{
printHeader("T2: Testing Default Constructor");
Ship invalid;
invalid.display();
invalid += Engine("D2", 2.1);
cout << endl;
}
Engine engines[] = {
Engine("V8", 4.4),
Engine("V8", 5.0),
Engine("Inline", 4.1),
Engine("D3", 7.0),
Engine("D0", 2.0),
Engine("D1", 3.2),
};
{
printHeader("T3: Testing Custom Constructor");
Ship titanic("cruiser", engines, 6);
titanic.display();
cout << endl;
}
{
printHeader("T4: Testing Conversion to Bool Operator");
Ship invalid;
Ship titanic("liner", engines, 1);
if (invalid)
cout << "1. Test Failed! Object should be invalid.\n";
else
cout << "1. Test succeeded!\n";
if (titanic)
cout << "2. Test succeeded!\n";
else
cout << "3. Test Failed! Object should be valid.\n";
cout << endl;
}
{
printHeader("T5: Testing += and < Operators");
Ship titanic("liner", engines, 3);
char type[]{ "D0" };
while (titanic < sdds::MIN_STD_POWER)
{
type[1]++;
cout << "Ship not up to standard. Required power: "
<< sdds::MIN_STD_POWER << endl;
titanic += Engine(type, 2.1);
}
titanic.display();
if (sdds::MAX_STD_POWER < titanic)
cout << "Too much power." << endl;
else
cout << "Ship doesn't exceed power regulation of: "
<< sdds::MAX_STD_POWER << endl;
}
return 0;
}
This is my engine.cpp file
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <string.h>
#include "Engine.h"
using namespace sdds;
using namespace std;
namespace sdds {
Engine::Engine(){ // Default Empty Engine
m_type[0] = '\0';
m_size = 0.0;
}
Engine::Engine(const char* type, double size){ // Custom Engine
strncpy(m_type, type, TYPE_MAX_SIZE);
m_size = size;
}
double Engine::get() const{ // Getter for the size of the engine
return m_size;
}
void Engine::display() const{ // Basic Display Function
cout << m_size << " liters - " << m_type << endl;
}
}
This is my ship.cpp where the error is in the += overloaded operator function.
#include <iostream>
#include <cstring>
#include "Ship.h"
using namespace std;
namespace sdds {
Ship::Ship(){ // Default Ship (empty)
m_type = nullptr;
m_engines = nullptr;
m_engCnt = 0;
}
Ship::Ship(const char* type, const Engine* engines, int engCnt){ // Custom Ship
if (type != nullptr && engines != nullptr && engCnt > 0) {
// creating a Valid Ship
int len = (unsigned)strlen(type);
m_type = new char[len + 1];
strcpy(m_type, type);
m_engines = new Engine[engCnt];
for (int i = 0; i < engCnt; i++) {
m_engines[i] = engines[i];
}
m_engCnt = engCnt;
}else{
m_type = nullptr; // Setting Ship to Empty State
m_engines = nullptr;
m_engCnt = 0;
}
}
Ship::~Ship(){
delete[] m_engines;
delete[] m_type;
}
Ship::operator bool() const {
// returning true if the ship is valid (not empty)
return m_type != nullptr;
}
Ship& Ship::operator+=(Engine e){ // THIS IS WHERE THE ERROR IS <-----------------
if (!*this) {
cout << "The object is not valid! Engine cannot be added!" << endl;
}else{
Engine* tmp = new Engine[m_engCnt + 1];
for (int i = 0; i <= m_engCnt; i++) {
tmp[i] = m_engines[i];
}
tmp[m_engCnt++] = e;
for (int i = 0; i <= m_engCnt; i++) {
m_engines[i] = tmp[i];
}
}
return *this;
}
double Ship::calculatePower() const { // Multiplying the Engines Size * 5 to get the power(sum of all)
double power = 0;
for (int i = 0; i < m_engCnt; i++) {
power += m_engines[i].get() * 5;
}
return power;
}
void Ship::display()const{ // Displaying the Ship
if (*this) {
streamsize dp = cout.precision(); // save default precision
cout.precision(2); // change default precision
cout << fixed; // enable fixed
cout << m_type << " - " << calculatePower() << endl;
for (int i = 0; i < m_engCnt; i++) {
m_engines[i].display(); // Engines Display function
}
cout.unsetf(ios::fixed); // disable fixed
cout.precision(dp); // restore default precision
}else{
cout << "No available data" << endl;
}
}
bool Ship::operator<(double power) const{ // Comparing the passed in power with the power of the ship
if (calculatePower() < power) {
return true;
}else{
return false;
}
}
bool operator<(double power, const Ship& theShip){ // Global < overloaded operator
if (power < theShip.calculatePower()) {
return true;
}else{
return false;
}
}
}

I need help using the "==" in this solution

The function contains(Object obj) returns true even though an object of that value is not in the pointer array. I have tried to overload the "==" function in my class Rec. It is using the function but the results are not what I want.
This is an attempt at a solution to a homework problem.
Design a class template, Collection, that stores a collection of Objects (in an array), along with the current size of the collection. Provide public functions isEmpty, makeEmpty, insert, remove, and contains. contains(x) returns true if and only if an Object that is equal to x is present in the collection.
I have tried other ways but I can't use nullptr as assignment.
#include "pch.h"
#include <iostream>
using namespace std;
template <typename Object>
class Collection {
public:
int ndx = 0;
Object *data[10] = { nullptr };
void insert(Object obj) {
if (ndx == 10) {
cout << "Container is full!!" << endl;
}
else {
data[ndx] = &obj;
//cout << data[ndx]->area() << endl;
++ndx;
cout << "Inserted in Location: " << ndx - 1 << endl;
}
}
void isEmpty() {
if (ndx > 0) {
cout << "Not empty " << ndx << " items!" << endl;
}
else {
cout << "Is empty, " << ndx << " items!" << endl;
}
}
void makeEmpty() {
for (int i = 0; i < ndx; i++)
data[i] = nullptr;
ndx = 0;
cout << "It is Empty!" << endl;
}
void remove(Object obj) {
cout << obj.area() << "here" << endl;
int index = -1;
for (int i = 0; i < ndx; i++) {
if (data[i] == obj) {
index = i;
}
}
if (index != -1) {
if (index == ndx - 1)
--ndx;
else {
for (int i = index; i < ndx; i++) {
data[i] = data[i + 1];
}
--ndx;
data[ndx] = nullptr;
}
cout << "Object Removed Location: " << index << endl;
}
else {
cout << "Object not found!" << endl;
}
}
bool contains(Object obj) {
for (int i = 0; i < ndx; i++) {
if (data[i] == obj) {
return true;
}
}
return false;
}
};
class Rec {
public:
int width;
int hieght;
void setValues(int &w, int &h) {
width = w;
hieght = h;
}
void setWidth(int &w) {
width = w;
}
void setHieght(int &h) {
hieght = h;
}
int area() { return width * hieght; };
bool operator==(const Rec& rhs)const {
cout << "used Normal" << endl;
return (width == rhs.width) && (hieght == rhs.hieght);
}
};
bool operator==(Rec * lhs, Rec rhs) {
cout << "used *" << endl;
return (lhs->width == rhs.width) && (lhs->hieght == rhs.hieght);
}
int main()
{
Collection<Rec> test;
for (int i = 0; i < 11; i++) {
Rec r;
r.setValues(i, i);
test.insert(r);
}
Rec r;
int i = 22;
r.setValues(i, i);
bool t = test.contains(r);
cout << "Here?: " << t << endl;
r.setValues(i, i);
test.remove(r);
test.makeEmpty();
//cout << test.data[6]->area() << endl;
return 0;
}
I want it to return false.

C++ linker undefined reference to function cannot find my error

It is a homework problem. It compiles fine, but linker gives undefined reference to my function getSalesData - line 20 just after my first for loop. Here is the code. I cannot find where I have done anything incorrectly; I have my prototype defined and it matches my function header, and I am simply calling the function.
// chips and salsa
#include <iostream>
#include <iomanip>
#include <string>
int getJarsSold(std::string type);
void getSalesData(int jarsSold[],int size,int &totalJars,int &highSeller,int &lowSeller);
int main() {
const int SIZE = 5;
const std::string salsaTypes[] {"Mild","Medium","Sweet","Hot","Zesty"};
int jarsSold[SIZE] = {};
int highIndex,lowIndex,totalJarsSold;
for (int i = 0; i < SIZE; i++) {
jarsSold[i] = getJarsSold(salsaTypes[i]);
}
getSalesData(jarsSold,SIZE,totalJarsSold,highIndex,lowIndex);
std::cout << " Type Jars Sold\n";
std::cout << "---------------------\n";
for (int i = 0; i < SIZE; i++) {
std::cout << std::setw(8) << salsaTypes[i] << std::setw(15) << jarsSold[i] << std::endl;
}
std::cout << "*********************\n";
std::cout << "Total Sales = " << totalJarsSold << std::endl;
std::cout << "Highest Seller = " << salsaTypes[highIndex] << std::endl;
std::cout << "Lowest Seller = " << salsaTypes[lowIndex] << std::endl;
}
int getJarsSold(std::string type) {
bool validData = false;
int numJars;
while (!validData) {
std::cout << "Enter jars sold this month for " << type << " salsa type: ";
std::cin >> numJars;
if (numJars < 0) {
std::cout << "Number of jars sold must be 0 or positive number.\n";
}
else {
validData = true;
}
}
validData = false;
return numJars;
}
void getSalesData(int jarsSold[],int size,int totalJars,int highIndex,int lowIndex) {
bool firstRun = true;
int highVal,lowVal;
totalJars = 0;
for (int i = 0; i < size; i++) {
if (firstRun) {
highIndex = i;
highVal = jarsSold[highIndex];
lowIndex = i;
lowVal = jarsSold[lowIndex];
totalJars += jarsSold[i];
firstRun = false;
}
else {
totalJars += jarsSold[i];
if (jarsSold[i] > highVal) {
highVal = jarsSold[i];
highIndex = i;
}
if (jarsSold[i] < lowVal) {
lowVal = jarsSold[i];
lowIndex = i;
}
}
}
}
Any help is appreciated. I am just using -c for compiling and -o for linking, nothing fancy as I know no better.

C1001 Compiling Error On Creation Of Class Object

When I Create An Instance of the following class using Game newGame; it throws a c1001 error stating that there was a compiler error.
game.h:
#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <conio.h>
#include "cls.h"
#include "explode.h"
using namespace std;
class Game
{
private:
explode EXP;
CLS cls;
string _SaveGame, _DIRECTORY;
int _GAMEDATA[500];
string _DATATITLES[500] = { "Ticks", "Dwarves", "Grain Mills", "Lumber Mills", "Mines", "Grain Workers", "Lumber Workers", "Mine Workers", "Grain Mill Experts", "Lumber Mill Experts", "Mine Experts" };
public:
void CS()
{
cls.clear();
}
void SetSaveName(string SaveName)
{
_SaveGame = SaveName;
}
void init(string directory)
{
_DIRECTORY = directory;
cout << "Init Game" << endl;
CS();
ofstream gameSave;
gameSave.open(_DIRECTORY + _SaveGame + ".save", ofstream::out | ofstream::app);
cout << "Game Saved As: " << _DIRECTORY + _SaveGame + ".save";
if (!gameSave.good())
{
// Write New Data To File
cout << "Game Saved As: " << _DIRECTORY + _SaveGame + ".save";
gameSave.flush();
gameSave << "0\n"; // TICKS
gameSave.flush();
gameSave << "7\n"; // Dwarves
gameSave.flush();
gameSave << "1\n"; // Grain Mills
gameSave.flush();
gameSave << "1\n"; // Lumber Mill
gameSave.flush();
gameSave << "1\n"; // Mine
gameSave.flush();
gameSave << "2\n"; // Grain Mill Workers
gameSave.flush();
gameSave << "2\n"; // Lumber Mill Workers
gameSave.flush();
gameSave << "3\n"; // Mine Workers
gameSave.flush();
gameSave << "1\n"; // Grain Mill Experts
gameSave.flush();
gameSave << "1\n"; // Lumber Mill Experts
gameSave.flush();
gameSave << "1\n"; // Mine Experts
gameSave.flush();
gameSave << "ENDFILE";
gameSave.flush();
}
else
{
// Read Data From File
loadGame(_SaveGame);
}
bool GameLoop = true;
while (GameLoop)
{
// Begin Game Loop Instance
printData();
string in;
bool parseDataLoop = 1;
while (parseDataLoop)
{
in = getData();
int parseDataInt = parseData(in);
if (parseDataInt == 1) {
GameLoop = 0;
saveGame();
exit(0);
}
else if (parseDataInt == 2) {
_getch();
}
else
{
parseDataLoop = 0;
}
}
saveGame();
}
}
void GameTick()
{
_GAMEDATA[0] += 1; // Number Of Game Ticks
}
void printData()
{
CS();
for (int i = 0; i < 500; i++) {
if (_GAMEDATA[i] != NULL) {
cout << _DATATITLES[i] << " : " << _GAMEDATA[i];
}
}
}
string getData()
{
string DATA;
cin >> DATA;
return DATA;
}
int parseData(string input)
{
int quit = 0;
if (input == "help")
{
// Print List Of Commands And Descriptions:
cout << "List Of All Available Commands:" << endl;
cout << "help : Shows A List Of All Available Commands" << endl;
cout << "tick : Makes Game Progress One Tick" << endl;
cout << "tick.NUM : Makes Game Progress NUM Tick(s)" << endl;
cout << "quit : Saves Game And Terminates Program" << endl;
quit = 2;
}
else if (input == "quit")
{
quit = 1;
}
else if (input == "tick")
{
// Skip One Tick
GameTick();
}
else if (find(input, '.')) {
vector<string> output;
output = EXP.explodeStuff(input, '.');
if (output[0] == "tick") {
if (isInterger(output[1]))
{
for (int i = 0; i < stoi(output[1]); i++) {
GameTick();
}
}
else
{
cout << "ERROR: tick." << output[1] << ", is not vaid please use numbers not letters." << endl;
quit = 2;
}
}
}
else
{
cout << "ERROR: Invalid Command Please type \"help\" To See A List Of Available Commands." << endl;
quit = 2;
}
return quit;
}
void loadGame(string saveGame)
{
ifstream inData;
string temp;
inData.open(_DIRECTORY + saveGame + ".cod");
if (inData.good())
{
for (int i = 0; i < 500; i++) {
getline(inData, temp);
if (temp == "ENDFILE") { break; }
if (temp != "")
{
_GAMEDATA[i] = stoi(temp);
}
}
inData.close();
}
}
void saveGame()
{
// Update Data in file
ofstream gameSave(_DIRECTORY + _SaveGame + ".save");
gameSave.clear();
for (int i = 0; i < 500; i++) {
if (_GAMEDATA[i] != NULL) {
gameSave << _GAMEDATA[i];
}
}
gameSave << "\nENDFILE";
}
bool find(string input, char find)
{
bool RETURN = 0;
for each (char CHAR in input)
{
if (CHAR == find) {
RETURN = 1;
break;
}
}
return RETURN;
}
inline bool isInterger(const std::string & s)
{
if (s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false;
char* p;
strtol(s.c_str(), &p, 10);
return (*p == 0);
}
};
main.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "game.h"
#include "programSettings.h"
#include "cls.h"
#include "explode.h" // Adds explode(string input, char delimeter), and explodePrint(vector<string> input)
using namespace std;
string _DIRECTORY = (string)getenv("APPDATA") + "/cityOfDwarves/";
vector<int> _SETTINGS; // Array To Hold All Settings In The SETTINGS.cod File
int SettingsConfigured;
explode EXP;
CLS cls;
int main()
{
SetConsoleTitle("CityOfDwarves");
programSettings pSet(_DIRECTORY);
_SETTINGS = pSet.readSettings();
if (_SETTINGS.size() > 0) {
SettingsConfigured = _SETTINGS[0];
}
else
{
SettingsConfigured = 0;
}
if (!SettingsConfigured) {
pSet.setSettings();
}
cout << "Settings Configured" << endl;
cls.clear();
cout << "Please Enter a Save Name:" << endl;
string SaveName;
cin >> SaveName;
cout << "Using: " << SaveName << ", As The Current Save File." << endl;
// Begin Game Loop
Game mainGame;
mainGame.SetSaveName(SaveName);
mainGame.init(_DIRECTORY);
char i;
cin >> i;
return 0;
}
Complete Error Code:
Severity Code Description Project File Line
Error C1001 An internal error has occurred in the compiler. CityOfDwarves C:\Users\Daniel\Documents\Visual Studio 2015\Projects\CityOfDwarves\CityOfDwarves\main.cpp 1