debugging error at the end of the console - c++

I'm a student and I studying c++.
This is my cpp code
int _tmain(int argc, _TCHAR* argv[])
{
CFood output;
output.whatFunc();
cout<<"my outputs"<<endl<<output<<endl;
return 0;
}
ostream& operator <<(ostream& outputStream, const CFood& output)
{
for(int i=0; i<2; i++)
{
outputStream <<"1 : "<<output.m_strName[i]<<" 2 : "<<output.m_servingSize[i]<<"g "<<"3 : "<<
output.m_calorie[i]<<"cal "<<"4 : "<<output.m_transFat[i]<<"g"<<endl;
}
return outputStream;
}
When I debug it, It work. But the end of the console, it gives me error message;;;
It says "An unhandled win32 exception occurred in work.exe [5796]"
My header filed is
class CFood
{
public:
CFood(void);
~CFood(void);
private:
string m_strName[7];
double m_servingSize[7];
double m_calorie[7];
double m_transFat[7];
public:
void whatFunc(void);
friend ostream& operator <<(ostream& outputStream,const CFood& output);
}
I think there is something wrong in my code..And I think it's CFood output;(Just thinking..)
Do you know why it has debug error?
++Sorry, I forgot the whatFunc(void)
This is code
void CFood::whatFunc(void) //
{
m_strName[0]="chicken";
m_strName[1]="rice";
m_strName[2]="meat";
m_strName[3]="strawberry";
m_strName[4]="apple";
m_strName[5]="water";
m_strName[6]="juice";
m_servingSize[0]=10;
m_servingSize[1]=20;
m_servingSize[2]=30;
m_servingSize[3]=40;
m_servingSize[4]=50;
m_servingSize[5]=60;
m_servingSize[6]=70;
m_calorie[0]=10.45;
m_calorie[1]=20.57;
m_calorie[2]=30.78;
m_calorie[3]=40.23;
m_calorie[4]=50.85;
m_calorie[5]=60.73;
m_calorie[6]=70.27;
m_transFat[0]=0.01;
m_transFat[1]=0.02;
m_transFat[2]=0.03;
m_transFat[3]=0.04;
m_transFat[4]=0.05;
m_transFat[5]=0.06;
m_transFat[6]=0.07;
}

Well its difficult to tell what exactly goes wrong without full source code. In my humble opinion, entire source lefts much to be desired. Placing obviously linked data in the bunch of the unlinked arrays with static size is not a very good pattern. Instead try something like that:
#include <iostream>
#include <vector>
#include <string>
#include <ostream>
struct CFoodItem{
std::string m_strName;
double m_servingSize;
double m_calorie;
double m_transFat;
};
class CFood
{
public:
void AddFoodItem(const CFoodItem& cItem);
friend std::ostream& operator <<(std::ostream& outputStream, const CFood& output);
private:
std::vector<CFoodItem> m_vItems;
};
std::ostream& operator <<(std::ostream& outputStream, const CFood& output)
{
for (auto i = output.m_vItems.begin(); i != output.m_vItems.end(); ++i)
{
outputStream << "1 : " << i->m_strName << " 2 : " << i->m_servingSize << "g " << "3 : " <<
i->m_calorie << "cal " << "4 : " << i->m_transFat << "g" << std::endl;
}
return (outputStream);
}
void CFood::AddFoodItem(const CFoodItem& cItem)
{
m_vItems.push_back(cItem);
}
int __cdecl main(void)
{
CFood output;
CFoodItem itm;
itm.m_strName = "some food";
itm.m_servingSize = 100500;
itm.m_calorie = 42;
itm.m_transFat = 42;
output.AddFoodItem(itm);
std::cout << "my outputs" << std::endl << output << std::endl;
return 0;
}

Related

Overloading operator<< twice in same class for different member variables

Sorry if this question has been asked before, but I'm struggling with overloading the << operator to stream different data into multiple files.
I have a Player class, which has the following attributes:
char* name;
char* password;
int hScore;
int totalGames;
int totalScore;
int avgScore;
I want to overload the << operator twice: one to stream the name, password and hScore to a "Players.txt" file, and a second overload to stream the totalGames, totalScore and avgScore to a different .txt file which is based off each player's name, e.g. "Player1.txt".
Here's what my operator looks like in the Player class:
friend ostream& operator<< (std::ostream& os, Player& player)
{
os << player.name << "\n" << player.encryptPassword((player.password), 3) << "\n" << player.hScore << "\n";
return os;
}
And here's where I am calling it, from a PlayerLibrary class which contains a vector of Players:
ofstream out("Yahtzee.txt");
if (out.is_open())
{
for_each(playerList.begin(), playerList.end(), [&out](Player* player) {out << (*player);});
}
else
{
cout << "THERE WAS AN ERROR WRITING TO FILE\n";
}
Basically, I want to stream the other variables into another file which is named after the player name, and contains a scorecard for each game they've played. So far it looks like:
for (auto it = playerList.begin(); it != playerList.end(); ++it)
{
auto position = it - playerList.begin();
string filename(playerList[position]->getName());
filename = filename + ".txt";
ofstream out2(filename);
for (int i = 0; i < playerList[position]->getNumberOfScorecards(); i++)
{
out2 << *playerList[position]->getScorecard(i);
}
}
This only streams the scorecard and not the totalGames, totalScore and avgScore, like I want it to.
I have tried just moving those variables into the scorecard class, but I feel that it makes more sense to have them where they are.
I understand that I can't overload operator<< twice if both overloads have the same parameters, is there another way of going about this? Is there anyway perhaps in the overloaded function to use the output stream and check the name of the .txt file or something.
Hope the question makes sense.
Rather than defining an operator<< for Player itself, create a couple of utility types that refer to the Player and have their own operator<<s, let them decide which portions of the Player to stream, eg:
class Player
{
private:
std::string name;
std::string password;
int hScore;
int totalGames;
int totalScore;
int avgScore;
...
public:
...
std::string getName{} const { return name; }
...
std::string EncryptPassword(int arg) const { return ...; }
int getNumberOfScorecards() const { return ...; }
Scorecard* getScorecard(int index) const { return ...; }
class Info
{
const Player &m_player;
void print(std::ostream &os) const {
os << m_player.name << "\n" << m_player.encryptPassword(3) << "\n" << m_player.hScore << "\n";
}
public:
Info(const Player &player) : m_player(player) {}
friend std::ostream& operator<<(std::ostream &os, const Info &info)
{
info.print(os);
return os;
}
};
friend class Info;
struct Stats
{
const Player &m_player;
void print(std::ostream &os) const
{
os << m_player.totalGames << "\n" << m_player.totalScore << "\n" << m_player.avgScore << "\n";
}
public:
Stats(const Player &player) : m_player(player) {}
friend std::ostream& operator<<(std::ostream &os, const Stats &stats)
{
stats.print(os);
return os;
}
};
friend class Stats;
};
And then you can use them like this:
ofstream out("Yahtzee.txt");
if (out.is_open())
{
for(auto *player : playerList)
out << Player::Info(*player);
}
else
{
cout << "THERE WAS AN ERROR WRITING TO FILE\n";
}
for (auto *player : playerList)
{
ofstream out2(player->getName() + ".txt");
out2 << Player::Stats(*player);
for (int i = 0; i < player->getNumberOfScorecards(); ++i)
{
out2 << *player->getScorecard(i);
}
}
Online Demo

How can I overload the << operator so I can write the data of an object to a file?

I have an object of type piggyBank and I need to write data of this object into a file and then read it. I am aware of how to write/read to a text file but how can I overload the << operator so I can write data about the object into a file?
My code for the class here:
piggyBank.h
#include <string>
#ifndef PIGGYBANK_H
#define PIGGYBANK_H
class PiggyBank
{
private:
std::string owner;
int balance;
bool broken;
int id;
static int nrOfObjects;
public:
PiggyBank(void);
PiggyBank(std::string name);
std::string getOwnerName() const;
void setOwnerName(std::string name);
bool isBroken() ;
int getBalance(int & amount) ;
};
#endif /* PIGGYBANK_H */
piggyBank.cpp
#include "PiggyBank.h"
#include "readWrite.h"
#include <string>
#include <iostream>
using namespace std;
int PiggyBank::nrOfObjects = 0; // outside constructor
PiggyBank::getNrOfObjects(){
return nrOfObjects;
}
PiggyBank::PiggyBank(void){
{this->owner="";this->balance=0;this->broken=false;}
id = ++nrOfObjects;
}
PiggyBank::PiggyBank(std::string name, int startBalance){
{this->owner=name;this->balance=startBalance;this->broken=false;}
id = ++nrOfObjects;
}
string PiggyBank::getOwnerName() const{
return this->owner;
}
void PiggyBank::setOwnerName(string name){
this->owner = name;
}
bool PiggyBank::isBroken() {
return this->broken;
}
int PiggyBank::getBalance(int & amount) {
if(!broken){
amount = balance;
return 0;
}else{
return -1;
}
}
You want the << operator to be a friend to the class and to return ostream&.
Here is a simple example to get an idea about how it works.
friend ostream& operator << (ostream& os, const PiggyBank& obj)
{
// For example something like this
os << "Information that you want to output to the file:\n";
os << "Owner: " << obj.owner << "\n";
return os;
}
And then you can use it like this:
PiggyBack obj;
ofstream fout("file.txt");
// also check to see if the file opened correctly
if(fout.fail())
{
cout << "File failed to open\n";
return 0;
}
fout << obj;
// now you have written the owner information onto the file as well as the message before it
// inside the operator<< overload
// close the resource at the end
fout.close();
The cool part is that you can use it to print to the console too by changing fout to be cout.
For example:
cout << obj; // will print to the console
Very simple. Overload the inserter operator. Write this into your class:
friend std::ostream& operator << (std::ostream& os, const PiggyBank& pb) {
return os << pb.owner << . . . // Whatever you want
Then you can use the inserter operator as for any other data type:
int main() {
PiggyBank pb;
if (std::ofstream os("FileName"); os) {
os << pb << "\n";
}
return 0;
}

C++ Operator overloading for << with abstract class

Here are my header files:
//Frame.h
#pragma once
class Frame {
string frameName;
protected:
double fileSize;
vector<Attribute> attributes;
public:
Frame(string f, double size, vector<Attribute> d) :frameName(f), fileSize(size), attributes(d) {}
virtual ~Frame() {}
string& GetFrameName() { return frameName; }
Attribute& operator[](int);
int size() { return attributes.size(); }
virtual void Compress() = 0;
friend ostream& operator<<(ostream&, Frame&);
};
// AudioFrame
#pragma once
class AudioFrame :public Frame {
static const int RATES = 3;
static constexpr double BITRATE[]{128,160,192};
static constexpr double COMPRESSION_RATIO[]{11.1,9.1,7.1};
public:
AudioFrame(string frameName, double fileSize, vector<Attribute> d) :Frame(frameName,fileSize, d) {}
~AudioFrame(){}
void Compress();
friend ostream& operator<<(ostream&, AudioFrame&);
};
//ImageFrame.h
#pragma once
class ImageFrame :public Frame {
static const int BITS = 8;
static constexpr double COMPRESSION_RATIO = 6.0;
static constexpr double BITDEPTH_FACTOR[] {11.1,4.6,3.5,2.4,1.9,1.5,1.2,1.0};
public:
ImageFrame(string fileName, double fileSize, vector<Attribute> d) :Frame(fileName, fileSize, d) {}
~ImageFrame(){}
void Compress();
friend ostream& operator<<(ostream&, ImageFrame&);
};
Each one of them have a **friend ostream& operator<<(ostream&, ImageFrame&);**
But when i do this
ImageFrame test;
cout << test << endl;
Only Frame class's operator << is called. Any solution to this?
Also, professor doesn't want me to change anything from the header files!
EDIT:
here is how i implement the operator <<:
// code from AudioFrame.cpp
ostream& operator<<(ostream& os, AudioFrame& obj) {
os << "AudioFrame" << endl;
os << "Name = " << obj.GetFrameName() << endl;
for (unsigned int i = 0; i < obj.attributes.size(); i++) {
os << "\tBandwidth #" << i << ": " << obj.attributes[i] << endl;
}
return os;
}
// code from ImageFrame.cpp
ostream& operator<<(ostream& os, ImageFrame& obj) {
os << "ImageFrame" << endl;
os << "Name = " << obj.GetFrameName() << endl;
for (unsigned int i = 0; i < obj.attributes.size(); i++) {
os << "\tResolution #" << i << ": " << obj.attributes[i] << endl;
}
return os;
}
// code from Frame.cpp
ostream& operator<<(ostream& os, Frame& obj) {
return os;
}
But when i run the test code, only the code from Frame.cpp is run.
EDIT2:
So i feel like i should also share my real test code:
int type;
deque<Frame*> frames; // all frames are stored here
// user is promoted a console menu for selecting a frame type (ImageFrame or AudioFrame)
if (type == 1)
frames.push_back(new AudioFrame(...));
else
frames.push_back(new ImageFrame(...));
// now when i need to print all frames i do
for (unsigned int i = 0; i < frames.size(); i++)
cout << *(frames[i]) << endl;
If you REALLY want cout << *(frames[i]) << endl; to dispatch polymorphically, and you REALLY cannot alter the headers, then you have no choice but to rely on dynamic typing.
ostream& operator<<(ostream& stream, Frame& frame) {
AudioFrame* as_audio_frame = dynamic_cast<AudioFrame*>(&frame);
ImageFrame* as_image_frame = dynamic_cast<ImageFrame*>(&frame);
if(as_audio_frame) {
return stream << *as_audio_frame;
}
if(as_image_frame) {
return stream << *as_image_frame;
}
//normal frame code
}
However, this is TERRIBLE code, and signals that some reorganizing is severely needed in the headers. So i suspect there is something wrong in your intrepretation of your assignment.
Edit, well, actually, there is a hilariously overengineered alternative...
class FrameAdapterInterface {
public:
virtual ~FrameAdapterInterface() {};
protected:
virtual std::ostream print(std::ostream&) = 0;
friend ostream& operator<<(ostream&, FrameAdapterInterface &);
};
template<typename FRAME_T>
class AdapatedFrameType : public FrameAdapterInterface {
FRAME_T data_;
public:
template<typename... ARGS_T>
AdapatedFrameType(ARGS_T&&... args)
: data_(std::forward<ARGS_T>(args)...) {}
ostream& print(std::ostream& stream) override {
return stream << data_;
}
};
ostream& FrameAdapterInterface::operator<<(ostream& stream, FrameAdapterInterface& frame) {
return frame.print(stream);
}

operator<< and stringstream overloading in c++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
Problem:
From overloaded operator<<, cout will only print first bit:``"Hello guys, ", while the stream is multiple shifts << "Hello guys, " << "I can't get here!" << str << "\n"`.
My question is, why I only get the first bit of stream?
Code:
#include <iostream>
#include <sstream>
#include <string>
class Debug {
private:
std::stringstream stream;
public:
std::string str() const{
return stream.str();
}
std::stringstream& operator<<(std::string &s) {
stream << s;
std::cout << s;
return stream;
}
std::stringstream& operator<<(const char s[]) {
stream << s;
std::cout << s;
return stream;
}
};
std::ostream &operator<<(std::ostream &output, const Debug &d) {
output << d.str();
return output;
}
int main() {
Debug debug;
std::string str("Bad input");
debug << "Hello guys, " << "I can't get here!" << str << "\n";
std::cout <<"\n\n"<< debug;
std::cin.get();
return 0;
}
My question is, why I only get the first bit of stream?
as it was mentioned in the comments, any further calls after the 1st one of the Debug::operator<<() overload, will go to the overloaded operator of std::stringstream because you return a reference to that one.
What you probably want is a class that wraps a std::ostream interface like follows:
class Debug {
std::ostream& os_;
public:
Debug(std::ostream& os) : os_(os) {}
template<typename T>
Debug& operator<<(T val) {
// Intercept whatever you want to intercept here ...
os_ << val;
return *this;
}
};
This will ensure that the Debug::operator<<() overload is called repeatedly when the statement
debug << "Hello guys, " << "I can't get here!" << str << "\n";
is going to be executed.
int main() {
Debug debug(std::cout);
std::string str("Bad input");
debug << "Hello guys, " << "I can't get here!" << str << "\n";
return 0;
}
Outputs:
Hello guys, I can't get here!Bad input
See the Live Demo.
To collect the stuff at an inner stream, and just output the contents at a certain point, you can do it as follows:
#include <iostream>
#include <string>
#include <sstream>
class Debug {
std::ostringstream os_;
public:
template<typename T>
Debug& operator<<(T val) {
os_ << val;
return *this;
}
// Overload the operator<< to output the buffered stuff
friend std::ostream& operator<<(std::ostream& os, const Debug& debug) {
os << debug.os_.str();
return os;
}
};
int main() {
Debug debug;
std::string str("Bad input");
debug << "Hello guys, " << "I can't get here!" << str << "\n";
std::cout << debug;
return 0;
}
Another Live Demo.

Retrieving values of an object from an array?

Pardon the example but in this case:
#include <iostream>
#include <string>
using namespace std;
class A {
private:
string theName;
int theAge;
public:
A() : theName(""), theAge(0) { }
A(string name, int age) : theName(name), theAge(age) { }
};
class B {
private:
A theArray[1];
public:
void set(const A value) {theArray[0] = value; }
A get() const { return theArray[0]; }
};
int main()
{
A man("Bob", 25);
B manPlace;
manPlace.set(man);
cout << manPlace.get();
return 0;
}
Is it possible for me to retrieve the contents of the "man" object in main when I call manPlace.get()? My intention is to print both the name (Bob) and the age (25) when I call manPlace.get(). I want to store an object within an array within another class and I can retrieve the contents of said array within the main.
You need to define a ostream::operator<< on your A class to accomplish that - otherwise the format how age and name should be generated as text-output is undefined (and they are private members of your A class).
Take a look at the reference for ostream::operator<<. For your A class, such a operator could be defined like this:
std::ostream& operator<< (std::ostream &out, A &a) {
out << "Name: " << a.theName << std::endl;
out << "Age: " << a.theAge << std::endl;
return out;
}
Which would output something like:
Name: XX
Age: YY
So your complete code would be:
#include <iostream>
#include <string>
using namespace std;
class A {
private:
string theName;
int theAge;
public:
A() : theName(""), theAge(0) { }
A(string name, int age) : theName(name), theAge(age) { }
friend std::ostream& operator<< (std::ostream &out, A &a) {
out << "Name: " << a.theName << std::endl;
out << "Age: " << a.theAge << std::endl;
return out;
}
};
class B {
private:
A theArray[1];
public:
void set(const A value) { theArray[0] = value; }
A get() const { return theArray[0]; }
};
int main()
{
A man("Bob", 25);
B manPlace;
manPlace.set(man);
cout << manPlace.get();
return 0;
}
which will output:
Name: Bob
Age: 25