reverse function doesn't reverse the referenced string of a class instantiation - c++

I'm trying to reverse the string from the FunnyNumber class. The problem is that when I call the method reverse in main on f2, it doesn't reverse the f2 string. But when I print out the reversed string from the reverse method implementation, it works. Also I overloaded the << operator to print out the string value in the class Number which is inherited in FunnyNumber class. Any help would be appreciated.
#ifndef NUMBER_H
#define NUMBER_H
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class Number {
public:
// Make a number with value 0
Number();
// Make a number with value val
Number(string val);
// Get the number's value
virtual string getValue() const;
// Print this number to the stream
virtual void print(ostream& stream) const;
// Read this number from the stream
virtual void read(istream& stream);
// Overload the insertion operator
friend ostream& operator <<(ostream& outs, const Number& n);
// Overload the extraction operator
friend istream& operator >> (istream& ins, Number& n);
protected:
string value;
};
#endif
Number::Number()
{
value = "";
}
Number::Number(string args)
{
value = args;
}
string Number::getValue()const
{
return value;
}
ostream& operator <<(ostream& outs, const Number& n)
{
n.print(outs);
return outs;
}
void Number::print(ostream& stream)const
{
stream << getValue();
}
void Number::read(istream& stream)
{
stream >> value;
}
istream& operator >> (istream& ins, Number& n)
{
n.read(ins);
return ins;
}
#ifndef FUNNYNUMBER_H
#define FUNNYNUMBER_H
#include<iostream>
#include<string>
#include"Number.h"
#include<algorithm>
using namespace std;
class FunnyNumber : public Number
{
public:
FunnyNumber();
FunnyNumber(string val);
virtual string operator+(const FunnyNumber &other)const;
virtual bool operator==(const FunnyNumber &other)const;
void reverse();
int find_first_not_this(char a);
protected:
string value;
};
#endif // !FUNNYNUMBERS_H
FunnyNumber::FunnyNumber()
{
value = "";
}
FunnyNumber::FunnyNumber(string val) : Number(val)
{
value = val;
}
string FunnyNumber::operator+ (const FunnyNumber& other)const
{
return getValue() + other.getValue();
}
int FunnyNumber::find_first_not_this(char a)
{
int pos = 0;
for(int i = 0; i < value.length(); i++)
{
if(value[i] != a)
{
pos = i;
return pos;
}
}
return pos;
}
bool FunnyNumber::operator==(const FunnyNumber& other)const
{
bool isEqual = true;
for (int i = 0; i < other.getValue().length(); i++)
{
bool found = false;
for (int j = 0; j < getValue().length(); j++)
{
if(getValue()[j] == other.getValue()[i])
{
found = true;
break;
}
}
if(!found)
{
isEqual = found;
return isEqual;
}
}
return isEqual;
}
void FunnyNumber::reverse()
{
std::reverse(value.begin(), value.end());
value.erase(0, find_first_not_this('0'));
}
#include <iostream>
#include<string.h>
#include "FunnyNumber.h"
using namespace std;
int main()
{
FunnyNumber f2;
f2 = FunnyNumber("223");
f2.reverse();
cout<<"Reversed value "<<f2<<endl;
system("pause");
return 0;
}
output is 223 instead of 322

Your FunnyNumber stores the value twice, once in a subobject of type Number, and once in string FunnyNumber::value.
Your reverse function modifies the second one, but doesn't have any effect on the Number base subobject. And then the only output function you call is working on the Number base subobject, and knows nothing about string FunnyNumber::value. That's why what is printed is not the result of reversal.

the overloaded operator << is a friend function on the Number class and friend functions are not inherited.
class Number {
public:
// Make a number with value 0
Number();
// Make a number with value val
Number(string &val);
// Get the number's value
virtual string getValue() const;
// Print this number to the stream
virtual void print(ostream& stream) const;
// Read this number from the stream
virtual void read(istream& stream);
// Overload the insertion operator
friend ostream& operator <<(ostream& outs, const Number& n);
// Overload the extraction operator
friend istream& operator >> (istream& ins, Number& n);
protected:
string *value;
};
Number::Number()
{
value = NULL;
}
Number::Number(string &args)
{
value = &args;
}
string Number::getValue()const
{
return *value;
}
ostream& operator <<(ostream& outs, const Number& n)
{
n.print(outs);
return outs;
}
void Number::print(ostream& stream)const
{
stream << getValue();
}
void Number::read(istream& stream)
{
stream >> *value;
}
istream& operator >> (istream& ins, Number& n)
{
n.read(ins);
return ins;
}

Related

Istream input checking

I have function, which recieves coeffecents of polynomial via istream input. Im struggling with implementing this piece of code into it (can't fully understand how istream& works), so i can shield it from incorrect input. :
while (!std::cin.good())
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "error";
std::cin >> A;
}
Into the function itself:
std::istream& operator>>(std::istream& s, Polynom& c)
{
for (int i = 0; i <= c.degree; i++)
s >> c.coefficents[i];
return s;
}
Needless to say, that's how it is implemented in main()
std::cin >> A;
Polynom class:
class Polynom
{
private:
int degree;
double* coefficents;
public:
Polynom();
Polynom(int size);
Polynom(const Polynom&);
~Polynom();
int get_degree();
double get_coefficents(int);
Polynom operator+(const Polynom&);
Polynom operator-(const Polynom&);
Polynom operator*(double p);
void operator=(const Polynom&);
friend std::ostream& operator<< (std::ostream& s, const Polynom& c);
friend std::istream& operator>> (std::istream& s, Polynom& c);
double& operator()(int i)
{
return coefficents[i];
}
};
Any hints or optimal solutions are welcomed :)
Expanding my comment to an answer, it's possible to make a function which takes the stream and uses the read-validation loop inside it to get the value.
Then in your operator>> overload you call this function to get each value.
Perhaps something like this:
template<typename T>
bool get_value(std::istream& input, T& value)
{
while (!(input >> value))
{
// If end of file, don't attempt any more validation
if (input.eof())
{
return false;
}
// Clear the error
input.clear();
// Ignore the rest of the line
input.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
// When the loop ends, we have successfully read a value from the stream
// Return true to tell that
return true;
}
You could use it as:
std::istream& operator>>(std::istream& s, Polynom& c)
{
double value;
for (int i = 0; i <= c.degree && get_value(s, value); i++)
c.coefficents[i] = value;
return s;
}

How to write/read classes within classes to binary file C++

I'm working on a project where I have to write a class that contains three other classes as private member variables to a binary file, where it can then be read back into variables to be used in the code. The code writes to the file, but I don't know if it is writing the correct info as when I try to read the file it reads in junk. I have included my current setup, does this look correct? If so, what could be going wrong, and if not, how can I fix this?
If you need me to add any extra code, please ask. Another consideration is that two of the classes being used as member functions for the players objects inherit from other classes.
if (cFile.is_open())
{
cFile.seekp(ios::beg);
for (int i = 0; i < 3; i++)
{
cFile.write(reinterpret_cast<char *>(&players[i]), sizeof(Character));
}
cFile.seekg(ios::beg);
for (int i = 0; i < 3; i++)
{
cFile.read(reinterpret_cast<char *>(&playersRead[i]), sizeof(Character));
playersRead[i].display();
}
cFile.close();
}
else
{
cout << "Error opening file." << endl;
}
I've been working on this code for a few days and am really having trouble. I appreciate any help I can get, thanks in advance.
#pragma once
#include <iostream>
using std::ostream;
#include "string.h"
#include "coinPouch.h"
#include "backpack.h"
class Character
{
public:
Character();
Character(String name);
Character(String name, CoinPouch wallet, Backpack storage);
Character(const Character & copy);
~Character();
Character & operator =(const Character & rhs);
friend ostream & operator << (ostream & out, const Character & c);
void purchase(int p, int g, int s, int c);
void income(int p, int g, int s, int c);
void addPotion(const Potion & toAdd);
void checkBalance();
void checkBackpack();
void changeName(const String & newN);
void display();
String getName();
CoinPouch getWallet();
Backpack getStorage();
void setName(String name);
void setWallet(CoinPouch wallet);
void setStorage(Backpack storage);
private:
String m_name;
CoinPouch m_wallet;
Backpack m_storage;
};
#include "character.h"
using std::endl;
using std::cout;
Character::Character() : m_name("Player")
{
CoinPouch initialW;
Backpack initialS;
m_wallet = initialW;
m_storage = initialS;
}
Character::Character(String name) : m_name(name)
{
CoinPouch initialW;
Backpack initialS;
m_wallet = initialW;
m_storage = initialS;
}
Character::Character(String name, CoinPouch wallet, Backpack storage) : m_name(name), m_wallet(wallet), m_storage(storage)
{
}
Character::Character(const Character & copy) : m_name(copy.m_name), m_wallet(copy.m_wallet), m_storage(copy.m_storage)
{
}
Character::~Character()
{
}
Character & Character::operator =(const Character & rhs)
{
if (this != &rhs)
{
m_name = rhs.m_name;
m_wallet = rhs.m_wallet;
m_storage = rhs.m_storage;
}
return *this;
}
ostream & operator << (ostream & out, const Character & c)
{
out << c.m_name << ": " << endl;
out << c.m_wallet << endl;
out << c.m_storage << endl;
return out;
}
void Character::purchase(int p, int g, int s, int c)
{
m_wallet.buy(p, g, s, c);
}
void Character::income(int p, int g, int s, int c)
{
m_wallet.add(p, g, s, c);
}
void Character::addPotion(const Potion & toAdd)
{
m_storage.addPotion(toAdd);
}
void Character::checkBalance()
{
m_wallet.display();
}
void Character::checkBackpack()
{
m_storage.displayContents();
}
void Character::changeName(const String & newN)
{
m_name = newN;
}
void Character::display()
{
cout << m_name << ": " << endl;
m_wallet.display();
m_storage.displayContents();
}
String Character::getName()
{
return m_name;
}
CoinPouch Character::getWallet()
{
return m_wallet;
}
Backpack Character::getStorage()
{
return m_storage;
}
void Character::setName(String name)
{
m_name = name;
}
void Character::setWallet(CoinPouch wallet)
{
m_wallet = wallet;
}
void Character::setStorage(Backpack storage)
{
m_storage = storage;
}
#pragma once
#include <iostream>
using std::ostream;
#include "string.h"
class CoinPouch
{
public:
CoinPouch();
CoinPouch(String init);
CoinPouch(int p, int g, int s, int c);
CoinPouch(const CoinPouch & copy);
~CoinPouch();
CoinPouch & operator = (const CoinPouch & rhs);
friend ostream & operator << (ostream & out, const CoinPouch & c);
void add(int p, int g, int s, int c);
bool checkCost(int p, int g, int s, int c);
void buy(int p, int g, int s, int c);
void convertCost();
void roundUp();
void display();
int getP();
int getG();
int getS();
int getC();
private:
String m_amount;
int m_platinum;
int m_gold;
int m_silver;
int m_copper;
};
#pragma once
#include "potions.h"
class DynamicArray
{
public:
// Constructors
DynamicArray();
~DynamicArray();
DynamicArray(const DynamicArray & copy);
// Op Equals
DynamicArray & operator =(const DynamicArray & rhs);
// Insert, delete, and get elements functions
int getElements();
void Insert(const Potion & add);
void Delete(const Potion & rmv);
void display();
// Overloaded operators
Potion & operator [](int index);
friend ostream & operator << (ostream & out, const DynamicArray & d);
private:
// Member variables
Potion * m_array;
int m_elements;
// Find function
int Find(const Potion & target);
};
#pragma once
#include "string.h"
#include <iostream>
using std::ostream;
class Potion
{
public:
// Constructors
Potion();
Potion(String name, String description, String potency, String cost);
Potion & operator = (const Potion & rhs);
Potion(const Potion & copy);
// Desctructor
~Potion();
// Overloaded operators
bool operator == (const Potion & rhs) const;
friend ostream & operator << (ostream & out, const Potion & p);
// Getter functions
String getName();
String getDesc();
String getPotency();
String getCost();
int getP();
int getG();
int getS();
int getC();
// Setter functions
void setName(String name);
void setDesc(String desc);
void setPotency(String potency);
void setCost(String cost);
// Convert and display functions
void convertCost();
void display();
private:
// Strings to hold item information
String m_name;
String m_description;
String m_potency;
String m_cost;
// Ints to hold cost information
int m_platinum;
int m_gold;
int m_silver;
int m_copper;
// Logical test
bool m_isnull = false;
};
#pragma once
#include <iostream>
using std::ostream;
class String
{
public:
// Constructors
String();
String(char ch);
String(const char * str);
// Destructor
~String();
// Copy Constructor and Copy Assignment Constructor
String(const String & copy);
String & operator=(const String & rhs);
friend ostream & operator << (ostream & out, const String & s);
// Added Functionality
void display();
void upper();
void lower();
// Operator Conversion
operator char *();
operator const char *();
// Overloaded operator
bool operator == (const String & rhs) const;
private:
// Member variables
char * m_str;
int m_ischar;
};
#pragma once
#include "dynamicarray.h"
#include "coinPouch.h"
#include "string.h"
class Backpack
{
public:
Backpack();
Backpack(DynamicArray potions);
Backpack(const Backpack & copy);
~Backpack();
Backpack & operator = (const Backpack & rhs);
friend ostream & operator << (ostream & out, const Backpack & c);
void addPotion(const Potion & add);
void usePotion(const Potion & rm);
void displayContents();
private:
DynamicArray m_potions;
int m_number;
};
This is a school project, and I am supposed to write the Character class to a binary file in order to save the characters so I can load them in on the program start. Right now I'm just trying to make sure that they can be successfully written to and read from the binary file and I have had no luck.
My bad, didn't know what to post and I didn't want to post everything in my file. Here is the character class. Let me know what else is needed, if anything.
It should be immediately obvious that this code can't possibly work.
cFile.write(reinterpret_cast<char *>(&players[i]), sizeof(Character));
However big sizeof(Character) is, we could have a Character with an m_name that takes up more bytes than that. So this code can't possibly be writing the character's name, and it clearly needs to do that.
Before you write anything to a file, decide on (and ideally, document) a file format at the byte level. Make sure your code writes in the format you documented and also can read in the format you documented. Skipping this step leads to pain and it also makes debugging impossible because you can't look at the file and compare it to a specification to see whether the writer or the reader is at fault.
Had you documented what bytes the player's name will occupy in the file, you'd immediately realize that you either need to have a variable-length object and encode the length somehow or pick a largest size name and allocate those many bytes. But because you skipped that vital step, you never actually worked out how to write a Character to a file.

Is it possible to get private variable value using class instance name?

For example, I've written a class called Length:
class Length {
public:
void setValue(float);
private:
float value_;
};
void
Length::setValue(float newValue) {
value_ = newValue;
}
void print(float value) {
std::cout << value;
}
void computeStuff(float value) {
//do the computing
}
int main() {
Length width;
width.setValue(5);
std::cout << width; // <-- this is actually just an example
//what I actually want is:
print(width); // print 5
//or perhaps even
computeStuff(width);
return 0;
}
Now how to make width return value_ or 5?
Technically, width is not an instance name, it's a name of a variable of type Length. You can change your code to retrieve a variable in two ways:
Add a friend operator << for Length that does the printing, or
Add an implicit conversion operator from Length to float.
The first approach works only for output. You cannot pull the value directly:
friend ostream& operator <<(ostream& out, const Length& len) {
out << len.value_;
return out;
}
The second approach looks like this:
class Length {
...
public:
operator float() const { return value_; }
};
You must overload operator<< for your custom type, something like:
class Length
{
..
friend std::ostream& operator<<(std::ostream& os, const Length& o);
..
}
std::ostream& operator<<(std::ostream& os, const Length& o)
{
os << o.value_;
return os;
}
Mind that this
must be non member
is nothing special , just an operator overload applied to a standard way of inserting things into stream of <iostream>
You need to define an operator() method to print the value 5.
You need to overload the << operator for your class. You could also use a function to do the operator's work.
Operator <<
#include <iostream>
class Length {
friend std::ostream& operator<<(std::ostream& os, const Length& l);
public:
void setValue(float);
private:
float value_;
};
void
Length::setValue(float newValue) {
value_ = newValue;
}
std::ostream& operator<<(std::ostream& os, const Length& l)
{
os << l.value_;
return os;
}
int main() {
Length width;
width.setValue(5);
std::cout << width << std::endl; // print 5
return 0;
}
function:
#include <iostream>
class Length {
friend std::ostream& print(std::ostream &,const Length &l);
public:
void setValue(float);
private:
float value_;
};
void
Length::setValue(float newValue) {
value_ = newValue;
}
std::ostream& print(std::ostream &os, const Length &l)
{
os << l.value_;
return os;
}
int main() {
Length width;
width.setValue(5);
print(std::cout, width) << std::endl;
return 0;
}

Overloading << error

I am kind of newbie to programming migrated from legacy turbo c++ to VS C++2012,I have a tough time catching up and i wanted to emulate the string library for TC. But i cant make the insertion operator work in this code....Please help Out. Could you tell the mistake i made in this code. And also why are we returning the object via reference for overloading.
#include<iostream>
#include<string>
namespace String
{
class string
{
char word[100];
int size;
public:
string()
{
size=0;
}
string(int sz)
{
size=sz;
}
string(char *Word)
{
strcpy(word,Word);
size=sizeof(*Word);
}
~string()
{
}
string &operator+(string Add)
{
strcat(word,Add.word);
return *this;
}
string &operator=(char *Word)
{
strcpy(word,Word);
return *this;
}
/*
ostream &operator<<(ostream &sout,string Show)
{
sout<<Show.word;
return sout;
}
*/
void Show()
{
std::cout<<word;
}
};
}
void main()
{
String::string A="ABCDEF";
String::string B="GHIJK";
String::string C;
C=A+B;
C.Show();
std::cin.ignore(2);
//std::cout<<C;
}
You should declare operator<< as a non-member function, because ostream will be taken as the 1st argument for operator<<, a user define type's member function can't satisfy it.
namespace String
{
class string
{
...
public:
ostream& put(ostream &sout) { sout << word; return sout; }
};
ostream& operator<<(ostream& sout, string Show) { return Show.put(sout); }
}
The output operator << has to be overloaded in the namespace, not the class itself if you want to be able to use it like so:
cout << my_class_object;
So, in the declaration of your class (string.h) add this line:
ostream &operator<<(ostream & sout,const string & Show);
And then in the definition file (string.cpp) in your namespace, not the class itself, ad this function:
ostream & operator<<( ostream & out, const bigint & data )
{
// the printing implementation
}

C++ friend function can't access private members

This is supposed to be a string class with a bunch of operators and functions, including two friend functions. And those two cause some trouble for me, because the compiler says that they can not access the private members. Here is my string.h:
#include <iostream>
#ifndef STR_H
#define STR_H
namespace MyStr
{
class Str
{
private:
unsigned int length;
char *data;
public:
Str();
Str(const Str&);
Str(const char*);
Str(char c, unsigned int db);
~Str();
char* cStr() const;
unsigned int getLength() const;
lots of irrevelant functions here...
friend int operator/ (const Str&, char);
friend std::ostream& operator<< (std::ostream&, const Str&);
};
}
#endif /* STR_H */
here is the main.cpp:
#include <iostream>
#include "Str.h"
using namespace std;
using namespace MyStr;
ostream& operator<< (ostream& out,const Str& str)
{
for (int i=0; i<str.length; i++)
{
out<<str.data[i];
}
out<<endl;
return out;
}
int operator/ (const Str& str, char c)
{
for (int i=0; i<str.length; i++)
{
if(str.data[i]==c) return i;
}
return -1;
}
This code won't compile, the compiler claiming that the Str members are private.
You should pay more attention to namespaces.
class Str {
private:
unsigned int length;
char *data;
public:
Str(){}
Str(const Str&){}
Str(const char*){}
Str(char c, unsigned int db){}
// maybe something more...
friend int operator/ (const Str&, char);
friend std::ostream& operator<< (std::ostream&, const Str&);
};
ostream& operator<< (ostream& out,const Str& str)
{
for (int i=0; i<str.length; i++)
out<<str.data[i];
out<<endl;
return out;
}
int operator/ (const Str& str, char c)
{
for (int i=0; i<str.length; i++)
if(str.data[i]==c) return i;
return -1;
}
int main()
{
Str s;
cout<<s;
return 0;
}
You get error because of the unmatched namespaces. If you prefer to stick with MyStr then you should add namespace MyStr to overloaded friend operators. This is how you can do it: (operators should be defined within namespace MyStr)
namespace MyStr {
ostream& operator<< (ostream& out,const Str& str)
{
for (int i=0; i<str.length; i++)
{
out<<str.data[i];
}
out<<endl;
return out;
}
int operator/ (const Str& str, char c)
{
for (int i=0; i<str.length; i++)
{
if(str.data[i]==c) return i;
}
return -1;
}
}
When you declare the friend functions inside Str they are considered to be in the immediately enclosing namespace, MyStr.
The operators you define are in the global namespace, so the compiler believes that those are two entirely different operators, and not the friends.
You can solve this by adding
namespace MyStr
{
}
around the operators in the .cpp file.