<< Operator Rewrite to cout int and double values - c++

I need to rewrite the << operator so that it can cout values for hour (int) and temperature (double).
I think I've included all necessary sections. Thanks in advance.
struct Reading {
int hour;
double temperature;
Reading(int h, double t): hour(h), temperature(t) { }
bool operator<(const Reading &r) const;
};
========
ostream& operator<<(ostream& ost, const Reading &r)
{
// unsure what to enter here
return ost;
}
========
vector<Reading> get_temps()
{
// stub version
cout << "Please enter name of input file name: ";
string name;
cin >> name;
ifstream ist(name.c_str());
if(!ist) error("can't open input file ", name);
vector<Reading> temps;
int hour;
double temperature;
while (ist >> hour >> temperature){
if (hour <0 || 23 <hour) error("hour out of range");
temps.push_back( Reading(hour,temperature));
}
}

For example like this:
bool operator <(Reading const& left, Reading const& right)
{
return left.temperature < right.temperature;
}
And it should be a global function (or in the same namespace as Reading), not a member or Reading, it should be declared as a friend if you going to have any protected or private members. This could be done like so:
struct Reading {
int hour;
double temperature;
Reading(int h, double t): hour(h), temperature(t) { }
friend bool operator <(Reading const& left, Reading const& right);
};

You probably want something like
ost << r.hour << ' ' << r.temperature;
This is pretty simple stuff though, and if it doesn't make sense you should really talk to someone or get a book.
And if it still doesn't make sense or you can't be bothered, consider choosing another hobby/career.

IIRC, you can do it one of two ways ...
// overload operator<
bool operator< ( const Reading & lhs, const Reading & rhs )
{
return lhs.temperature < rhs.temperature;
}
or, you can add the operator to your struct ...
struct Reading {
int hour;
double temperature;
Reading ( int h, double t ) : hour ( h ), temperature ( t ) { }
bool operator< ( const Reading & other ) { return temperature < other.temperature; }
}

Use ost parameter like std::cout in operator<<.

r.hour()
r.temperature()
You've declared hour and temperature as member fields of Reading, not member methods. Thus they are simply r.hour and r.temperature (no ()).

As hour and temperature are variables rather than functions, just remove the trailing () from the operator<< functions.

You can overload an operator like this in c++.
struct Reading {
int hour;
double temperature;
Reading(int h, double t): hour(h), temperature(t) { }
bool operator<(struct Reading &other) {
//do your comparisons between this and other and return a value
}
}

Related

c++ read .csv file, place data into variables and then into an object

hi reached a point where im not sure how to proceed.
the main objective of my program:
1) read 5 values from a file(.csv)
date (class with 3 variables - day,month, year)
time (class with 2 variables - minute, hour)
float wSpeed (under class weather)
float temperature (under class weather)
float solarRadiation (under class weather)
2) put into an object
3) put it into a vector
main
int main()
{
string filename;
ifstream input;
Vector<weather> windlog; //have a vector called windlog
cout <<"enter file name:" <<endl;
cin >> filename;
input.open(filename.c_str());
input.ignore(500,'\n');
string sDay, sMonth, sYear, sHH, sMM, wind, solar, temperature;
date d1;
time t1;
weather w1;
getline(input, sDay,'/'); //stop getting input at '/'
getline(input, sMonth,'/');
getline(input, sYear,' ');
getline(input, sHH,':');
getline(input, sMM,',');
int day1 = atoi(sDay.c_str()); //convert string to int (atoi)
int month1 = atoi(sMonth.c_str());
int year1 = atoi(sYear.c_str());
int hour1 = atoi(sHH.c_str());
int min1 = atoi(sMM.c_str());
d1.setDate(day1,month1,year1); //set date using converted string
t1.setTime(min1, hour1); //set time using converted string
// skip the first 9 columns of .csv file
for(int i=0; i<9; i++)
{
input.ignore(50, ','); //ignore ','
}
//location now at wSpeed date of .csv file
getline(input, wind,',');
float wS1 = atof(wind.c_str()); // convert string to float
//next location is the location solarRadiation
getline(input, solar,',');
float sR1= atof(solar.c_str()); // convert string to float
//move 5 columns
for(int i=0; i< 5; i++)
{
input.ignore(50, ',');
}
//at location of temperature
getline(input, temperature,'\n');
float temperature1 = atof(temperature.c_str()); // convert string to
float
//when i print it out, it gives me the correct data
/*
cout << d1; //date class that contains dd,mm,yy
cout << t1;//time class that contains hh, mm
cout << wS1 ;
cout << sR1;
cout << temperature1 << endl;
*/
//trying to put these data into an object file: weather
//i tried doing something like this
weather obj1(wS1, sR1, temperature1, d1, t1);
cout << objt1;//gives me weird values but when i cout each variable, it
works out fine
not going to write the whole date/time.h/cpp cause i think it'll take up too much space
date.h
public:
setday, setmonth, setyear, setdate(day,month,year);
getday,getmonth,getyear;
private: day,month,year;
time.h
public:
setminute, sethour, settime(minute,hour);
getminute,get hour;
private: minute, hour;
weather class(where im having the problems)
.H
#ifndef H_WEATHER
#define H_WEATHER
#include <iostream>
#include <string>
#include "time.h"
#include "date.h"
using namespace std;
class weather: public date, time
{
friend ostream& operator << (ostream&, const weather&);
friend istream& operator >> (istream&, weather&);
public:
weather();
weather(float wSpeed, float solarRadiation, float temperature,
date d1, time t1);
~weather();
void setWspeed(float wSpeed);
void setSolarRadiation(float solarRadiation);
void setTemperature(float temperature);
float getWspeed() const ;
float getSolarRadiation() const;
float getTemperature() const;
void setWeather(float wS, float sR, float t,date d1, time t1);
date getDate();
time getTime();
date d1;//mm, hh
time t1;//dd,mm,yy
private:
float wSpeed;
float solarRadiation;
float temperature;
};
#endif
.CPP
#include <iostream>
#include "weather.h"
#include "date.h"
#include "time.h"
weather::weather()
{
wSpeed=0;
solarRadiation=0;
temperature = 0;
}
weather::weather(float wS, float sR, float t, date d1, time
t1):date(day,month,year), time(hours,minute)
{
wS = wS;
sR = sR;
t =t;
d1.setDate(day,month, year);
t1.setTime(hours,minute);
}
weather::~weather() {}
void weather::setWeather(float wS, float sR, float t)
{
wSpeed =wS;
solarRadiation=sR;
temperature =t;
}
void weather::setWspeed(float wS)
{
wSpeed =wS;
}
void weather::setSolarRadiation(float sR)
{
solarRadiation=sR;
}
void weather::setTemperature(float t)
{
temperature = t;
}
void weather::setWeather(float wS,float sR, float t, date d1, time
t1)
{
wSpeed=wS;
solarRadiation=sR;
temperature = t;
}
float weather::getWspeed() const
{
return wSpeed;
}
float weather::getSolarRadiation() const
{
return solarRadiation;
}
float weather::getTemperature() const
{
return temperature;
}
ostream& operator<< (ostream& osObject, const weather& weather1)
{
osObject << weather1.wSpeed <<" " << weather1.solarRadiation <<""
<< weather1.temperature << weather1.d1 << weather1.t1 ;
return osObject;
}
istream& operator >> (istream& isObject, weather& weather1)
{
isObject >> weather1.wSpeed>> weather1.solarRadiation >>
weather1.temperature >> weather1.d1 >> weather1.t1;
return isObject;
}
how do i put the values into an object? is it correct i have to use inheritance so i can overload the weather constructor so it can take a date and time class?
You almost have it, but...
You do NOT have to inherit to be able to work with a member object. In
class weather: public date, time
: public date, time is not necessary. It also implies the weather is a date and a time which makes no sense. Avoid inheriting unless there is some logical is-a relationship.
weather::weather(float wS, float sR, float t, date d1, time t1):
date(day,month,year), // you want the member name now, not the type
// plus where did day month and year come from?
time(hours,minute) // not ditto, but close enough.
{
wS = wS; // self assigns. In other word, does nothing
sR = sR; // ditto
t =t; // ditto
d1.setDate(day,month, year); // where did day month and year come from?
t1.setTime(hours,minute); // not ditto, but close enough.
}
Doesn't really do anything. It mostly has the parameters assigning to themselves. This is pointless because they are the same variable and they are temporary variables. What you want to do is assign to the member variables. This is a constructor, so you might as well use the Member Initializer List all the way through
weather::weather(float wS,
float sR,
float t,
date d1,
time t1) :
wSpeed(wS),
solarRadiation(sR),
temperature(t),
d1(d1), // note this is about the only time you can use the same name twice.
// Enjoy it. But don't do it. It confuses people.
t1(t1) // ditto
{
}
Then we get down to setWeather
void weather::setWeather(float wS, float sR, float t)
{
wSpeed =wS;
solarRadiation=sR;
temperature =t;
}
Does not match the definition in the class
void setWeather(float wS, float sR, float t,date d1, time t1);
So obviously we want something more like
void weather::setWeather(float wS, float sR, float t, date pd1, time pt1)
{
wSpeed = wS;
solarRadiation = sR;
temperature = t;
d1 = pd1;
t1 = pt1;
}
Note I did not repeat d1 in the parameter list. I changed it so I wouldn't have d1 = d1; which does nothing useful. It would be better to give both the member and the parameter more descriptive names. d1 conveys zero information about that the variable is and how it should be used.

>> operator overloading...C++

I'm just a new to C++ And i'm at the beginning...Just want some help...would be appreciate it if somebody can explain where am I wrong with this:
First of all my Time.h code:
#ifndef TIME_H
#define TIME_H
#include<iostream>
using namespace std;
class time {
friend istream &operator>> (istream &, time);
private:
int hour;
int minute;
int second;
public:
time(int = 0, int = 0, int = 0);
void settime(int, int, int);
void sethour(int);
void setminute(int);
void setsecond(int);
};
#endif
And now, Time.cpp:
#include<iostream>
#include"Time.h"
using namespace std;
using std::cout;
using std::cin;
time::time(int h, int m, int s)
{
settime(h, m, s);
}
void time::settime(int hr, int min, int sec)
{
sethour(hr);
setminute(min);
setsecond(sec);
}
void time::sethour(int h)
{
hour = (h >= 0 && h < 24) ? h : 0;
}
void time::setminute(int m)
{
minute = (m >= 0 && m < 60) ? m : 0;
}
void time::setsecond(int s)
{
second = (s >= 0 && s < 60) ? s : 0;
}
istream &operator>> (istream &in, time m)
{
in >> m.sethour >> m.setminute >> m.setsecond;
}
And finally source.cpp:
#include<iostream>
#include"D:\headers\Time.h"
using namespace std;
void main()
{
time t;
cin >> t;
system("pause");
}
But when I compile it, it gives me an error:
1.Error C3867 'time::sethour': non-standard syntax; use '&' to create a pointer to member Project33 D:\headers\Time.cpp
2.Error C2679 binary '>>': no operator found which takes a right-hand operand of type 'overloaded-function' (or there is no acceptable conversion) Project33 D:\headers\Time.cpp
Can anybody help me out???
sethour is a member function not a member variable. You need to use a variable.
You can use:
istream &operator>> (istream &in, time m)
{
return (in >> m.hour >> m.minute >> m.second);
}
However, that won't do the calling function any good because you are changing a copy. You need to pass m by reference.
istream &operator>> (istream &in, time& m)
{
return (in >> m.hour >> m.minute >> m.second);
}
Make sure to change the declaration accordingly.
Had the function not been a friend of the class, you could use:
istream &operator>> (istream &in, time& m)
{
// Read the data.
int hour;
int minute;
int second;
in >> m.hour >> m.minute >> m.second;
// Set the member values using function calls.
m.sethour(hour);
m.setminute(minute);
m.setsecond(second);
return in;
}
You're reading into functions here:
in >> m.sethour >> m.setminute >> m.setsecond;
^ ^ ^
That's a simple typo. The bigger problem is that you take the time by value, which prevents any modifications from it to propagating; you probably wanted to take a reference there.

How to print class object using operator<<

I want to write a print function for a class AutoData that has information about cars in it. With this print function, I would ideally like to print out a vector that contains many different class objects. I have already written get functions for each element of the objects, but I am still a bit unsure of how to go about using those to write a function to print out the data in the following format:
mpg:cylinders:displacement:horsepower:weight:acceleration:modelYear:origin:carName
For example:
10.0:8:360.0:215.0:4615.:14.0:70:1:ford f250
10.0:8:307.0:200.0:4376.:15.0:70:1:chevy c20
11.0:8:318.0:210.0:4382.:13.5:70:1:dodge d200
The class is:
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class AutoData {
public:
AutoData()
{
mpg = 0;
cylinders = 0;
displacement = 0;
horsepower = 0;
weight = 0;
acceleration = 0;
modelYear = 0;
origin = 0;
carName = "";
}
AutoData( const AutoData & rhs)
{
setAuto(rhs.mpg, rhs.cylinders, rhs.displacement, rhs.horsepower, rhs.weight, rhs.acceleration, rhs.modelYear, rhs.origin, rhs.carName);
}
void setAuto(float mp, int cy, float di, float ho, float we, float ac, int mo, int o, string ca)
{
mpg = mp;
cylinders = cy;
displacement = di;
horsepower = ho;
weight = we;
acceleration = ac;
modelYear = mo;
origin = o;
carName = ca;
}
const float & getmpg( ) const
{
return mpg;
}
const int & getcylinders( ) const
{
return cylinders;
}
const float & getdisplacement( ) const
{
return displacement;
}
const float & gethorsepower( ) const
{
return horsepower;
}
const float & getweight( ) const
{
return weight;
}
const float & getacceleration( ) const
{
return acceleration;
}
const int & getmodelYear( ) const
{
return modelYear;
}
const int & getorigin( ) const
{
return origin;
}
const string & getcarName( ) const
{
return carName;
}
bool operator == (const AutoData & rhs ) const
{
if( getmpg( ) == rhs.getmpg( ) )
{
return gethorsepower( ) == rhs.gethorsepower( );
}
else
{
return false;
}
}
bool operator > ( const AutoData & rhs ) const
{
if( rhs.getmpg( ) > getmpg( ) )
{
return true;
}
else if( getmpg( ) == rhs.getmpg( ) )
{
if( rhs.gethorsepower( ) > gethorsepower( ) )
{
return true;
}
}
else
{
return false;
}
}
private:
float mpg;
int cylinders;
float displacement;
float horsepower;
float weight;
float acceleration;
int modelYear;
int origin;
string carName;
};
Any help/advice anyone can provide would be very much appreciated!! Thanks
If you want to be able to do std::cout << AutoData();, you need to overload the output stream operator operator<<:
std::ostream& operator<< (std::ostream &out, AutoData const& data) {
out << data.getmpg() << ':';
out << data.getcylinders() << ':';
// and so on...
return out;
}
This function is not a member function, and since you have getters for each attribute, you do not have to declare this function as friend of your class.
Then you can do:
AutoData myAuto;
std::cout << myAuto << '\n';
What have you tried so far? My approach would be overloading operator<<, like:
std::ostream& operator<<(std::ostream& out, const AutoData& dasAuto) {
return out << dasAuto.getmpg() << ':' << dasAuto.getcylinders() <<
/* insert everthing in the desired order here */
std::endl;
}
And the same thing for the "reading" function, like:
std::istream& operator>>(std::istream& in, AutoData& dasAuto) {
float mpg;
int cylinders;
float displacement;
float horsepower;
float weight;
float acceleration;
int modelYear;
int origin;
string carName;
char separator;
const char SEP = ':';
if( !(in >> mpg >> separator) || (separator != SEP) ) return in;
if( !(in >> cylinders >> separator) || (separator != SEP) ) return in;
/* rinse, repeat */
if( !std::getline(in, carName) ) return in;
dasAuto.setAuto(mpg, cylinders /*, etc etc */);
return in;
}
You can read this artical to know about friend and operator <<,
http://www.cprogramming.com/tutorial/friends.html
In the class AutoData, you should declare this function:
friend ostream& operator<< (ostream& out, const AutoData& obj);
outside the class, you should define this function like this:
ostream& operator<< (ostream& out, const AutoData& obj)
{
out<<obj.mpg<<":";
//do what you want
return out;
}

<< Operator Rewrite. Error from struct "cannot be used as a function" [duplicate]

I need to rewrite the << operator so that it can cout values for hour (int) and temperature (double).
I think I've included all necessary sections. Thanks in advance.
struct Reading {
int hour;
double temperature;
Reading(int h, double t): hour(h), temperature(t) { }
bool operator<(const Reading &r) const;
};
========
ostream& operator<<(ostream& ost, const Reading &r)
{
// unsure what to enter here
return ost;
}
========
vector<Reading> get_temps()
{
// stub version
cout << "Please enter name of input file name: ";
string name;
cin >> name;
ifstream ist(name.c_str());
if(!ist) error("can't open input file ", name);
vector<Reading> temps;
int hour;
double temperature;
while (ist >> hour >> temperature){
if (hour <0 || 23 <hour) error("hour out of range");
temps.push_back( Reading(hour,temperature));
}
}
For example like this:
bool operator <(Reading const& left, Reading const& right)
{
return left.temperature < right.temperature;
}
And it should be a global function (or in the same namespace as Reading), not a member or Reading, it should be declared as a friend if you going to have any protected or private members. This could be done like so:
struct Reading {
int hour;
double temperature;
Reading(int h, double t): hour(h), temperature(t) { }
friend bool operator <(Reading const& left, Reading const& right);
};
You probably want something like
ost << r.hour << ' ' << r.temperature;
This is pretty simple stuff though, and if it doesn't make sense you should really talk to someone or get a book.
And if it still doesn't make sense or you can't be bothered, consider choosing another hobby/career.
IIRC, you can do it one of two ways ...
// overload operator<
bool operator< ( const Reading & lhs, const Reading & rhs )
{
return lhs.temperature < rhs.temperature;
}
or, you can add the operator to your struct ...
struct Reading {
int hour;
double temperature;
Reading ( int h, double t ) : hour ( h ), temperature ( t ) { }
bool operator< ( const Reading & other ) { return temperature < other.temperature; }
}
Use ost parameter like std::cout in operator<<.
r.hour()
r.temperature()
You've declared hour and temperature as member fields of Reading, not member methods. Thus they are simply r.hour and r.temperature (no ()).
As hour and temperature are variables rather than functions, just remove the trailing () from the operator<< functions.
You can overload an operator like this in c++.
struct Reading {
int hour;
double temperature;
Reading(int h, double t): hour(h), temperature(t) { }
bool operator<(struct Reading &other) {
//do your comparisons between this and other and return a value
}
}

C++ Operator and Conversion Issues

double mean(vector<Reading> temps)
{
// stub version
double mean_temp;
double sum = 0;
for (int i = 0; i< temps.size(); ++i) sum += temps[i];
mean_temp = sum/temps.size();
return (mean_temp);
}
double median(vector<Reading> temps)
{
// stub version
double median_temp;
sort (temps.begin(), temps.end());
median_temp = temps[temps.size()/2];
return (median_temp);
}
============================================
Result in errors:
proj4.cc: In function ‘double mean(Vector<Reading>)’:
proj4.cc:132: error: no match for ‘operator+=’ in ‘sum += temps.Vector<T>::operator[] [with T = Reading](((unsigned int)i))’
proj4.cc: In function ‘double median(Vector<Reading>)’:
proj4.cc:142: error: cannot convert ‘Reading’ to ‘double’ in assignment
=============================================
Full code below. I need to tackle these two errors before I can proceed
#include <bjarne/std_lib_facilities.h>
struct Reading {
int hour;
double temperature;
Reading(int h, double t): hour(h), temperature(t) { }
bool operator<(const Reading &r) const;
};
bool Reading::operator<(const Reading &r) const
{
// stub version
vector<Reading> temps;
sort (temps.begin(), temps.end());
}
/*
* function declarations
*/
ostream& operator<<(ostream& ost, const Reading &r);
vector<Reading> get_temps();
double check_adjust_temp(double temperature, char scale);
double c_to_f(double temperature);
double mean(vector<Reading> temps);
double median(vector<Reading> temps);
void print_results(const vector<Reading>& temps, double mean_temp,
double median_temp);
int main()
try
{
vector<Reading> temps = get_temps();
if (temps.size() == 0) error("no temperatures given!");
double mean_temp = mean(temps);
sort(temps.begin(), temps.end());
double median_temp = median(temps);
print_results(temps, mean_temp, median_temp);
}
catch (exception& e) {
cerr << "error: " << e.what() << '\n';
return 1;
}
catch (...) {
cerr << "Oops: unknown exception!\n";
return 2;
}
/*
* function definitions
*/
ostream& operator<<(ostream& ost, const Reading &r)
{
// stub version
/*
*/
return ost;
}
vector<Reading> get_temps()
{
// stub version
cout << "Please enter name of input file name: ";
string name;
cin >> name;
ifstream ist(name.c_str());
if(!ist) error("can't open input file ", name);
vector<Reading> temps;
int hour;
double temperature;
while (ist >> hour >> temperature){
if (hour <0 || 23 <hour) error("hour out of range");
temps.push_back( Reading(hour,temperature));
}
}
double check_adjust_temp(double temperature, char scale)
{
// stub version
if (scale== 'c' || 'C'){
return c_to_f(temperature);
}
else if (scale== 'f' || 'F') {
return temperature;
}
else {
error("Wrong input type");
}
}
double c_to_f(double temperature)
{
// stub version
double c;
c = ((temperature * (9.0/5)) + 32);
return (c);
}
double mean(vector<Reading> temps)
{
// stub version
double mean_temp;
double sum = 0;
for (int i = 0; i< temps.size(); ++i) sum += temps[i];
mean_temp = sum/temps.size();
return (mean_temp);
}
double median(vector<Reading> temps)
{
// stub version
double median_temp;
sort (temps.begin(), temps.end());
median_temp = temps[temps.size()/2];
return (median_temp);
}
void print_results(const vector<Reading>& temps, double mean_temp,
double median_temp)
{
// stub version
cout << "The sorted temperatures are:\n";
cout << get_temps;
cout << "The mean temperature is " << mean_temp << ".\n";
cout << "The median temperature is " << median_temp << ".\n";
}
Define a conversion operator for Reading:
struct Reading {
int hour;
double temperature;
Reading(int h, double t): hour(h), temperature(t) { }
bool operator<(const Reading &r) const;
operator double() { return temperature; }
};
Or, better (via the Principle of Least Astonishment), just change the usage of your class:
// was:
sum += temps[i];
//change to:
sum += temps[i].temperature;
// was:
median_temp = temps[temps.size()/2];
//change to:
median_temp = temps[temps.size()/2].temperature;
You're trying to execute an addition between an instance of a class Reading and a double. This doesn't work as long as you don't provide either a default conversion path from Reading to double:
Reading::operator double() const { return temperature; }
or by providing proper global operator+() overloads:
double operator+(Reading const&, double);
double operator+(double, Reading const&);
The second error should be solvable with the Reading::operator double() as shown above.
You are missing operator+= for the class Reading
you are trying to sum up Reading objects into a double variable!
sum += temps[i];
sum type is double while temps[i] returns Reading object, you cannot sum double and Reading object since they belong to different types, you must define an overload of plus operator and make the compiler understand how this is done.