C++/still on my increment operator
Expert: vijayan - 12/12/2008
QuestionQUESTION: Hello,
I have the code this way but when i compile and run the programme, it's doing nothing. supoose i want that when i enter a time say: 12:04, i want it to display both the increment and decrement of the time i.e : 12:05 and 12:04. Below is the code:
#include <iostream>
#include <stdexcept>
using namespace std;
class Time
{
public:
Time(int _hr, int _min) : min( _min ), hr( _hr )
{
if( ( hr >= 0 && hr < 24 ) || ( min >= 0 && min < 24 ) )
throw std::range_error( "incorrect time" ) ;
}
enum { MINUTES_PER_DAY = 60 * 24 } ;
explicit Time( int _asMin = 0 )
{
if( ( _asMin < 0 ) || ( _asMin >= MINUTES_PER_DAY ) )
throw std::range_error( "incorrect time" ) ;
hr = _asMin/60; min = _asMin%60 ;
};
friend ostream &operator<<(ostream &out, const Time &t2);
friend istream &operator>>(istream &in, Time &t2);
Time operator++(int); //postfix increment
Time& operator++(); //prefix increment
int getTmin(){return hr*60 + min;}
// etc
private:
int min;
int hr;
// int count;
};
Time Time::operator++(int)
{
Time old = *this;
*this = Time( ( getTmin() + 1 ) % Time::MINUTES_PER_DAY );
++*this ; // do exactly what prefix increment does
return old;
}
Time& Time::operator++()
{
*this = Time( ( getTmin() + 1 ) % Time::MINUTES_PER_DAY );
return *this;
}
ostream &operator<<(ostream &out, const Time& t2 )
{ return out << t2.hr << ' ' << t2.min ; }
istream &operator>> ( istream &in, Time& t2 )
{
int hr, min ;
if( ( in >> hr >> min ) &&
( hr >= 0 && hr < 24 ) && ( min >= 0 && min < 60 ) )
{
t2.hr = hr ;
t2.min = min ;
}
else in.clear( ios::failbit ) ; // set stream to failed state
return in ;
}
int main(void)
{
Time time;
cout << "Enter time :" ;
cin >> time;
cout << time++ << '\n' ;
cout << ++time << '\n' ;
}
ANSWER: there is an error in the overloaded prefix increment operator: the time is incremented twice.
Time Time::operator++(int)
{
Time old = *this;
// this increments time once
*this = Time( ( getTmin() + 1 ) % Time::MINUTES_PER_DAY );
// this increments time once more
++*this ; // do exactly what prefix increment does
return old;
}
you need only one of the two, not both.
> i want it to display both the increment and decrement of the time
easy, also implement the overloaded decrement operators for time.
and then write main as:
int main(void)
{
Time time;
cout << "Enter time :" ;
cin >> time;
cout << time++ << '\n' ;
cout << time << '\n' ;
cout << ++time << '\n' ;
cout << --time << '\n' ;
cout << time-- << '\n' ;
cout << time << '\n' ;
}
---------- FOLLOW-UP ----------
QUESTION: Hello,
I have done all you have asked me to do except that i have decided to leave out the decrement overload. i just want the programme to use the post and pre increment overload in the programme but when i enter a time say : 12:05 it's giving me zeroes. please culd you compile the programme and see for urself?
#include <iostream>
#include <stdexcept>
using namespace std;
class Time
{
public:
Time(int _hr, int _min) : min( _min ), hr( _hr )
{
if( ( hr >= 0 && hr < 24 ) || ( min >= 0 && min < 24 ) )
throw std::range_error( "incorrect time" ) ;
}
enum { MINUTES_PER_DAY = 60 * 24 } ;
explicit Time( int _asMin = 0 )
{
if( ( _asMin < 0 ) || ( _asMin >= MINUTES_PER_DAY ) )
throw std::range_error( "incorrect time" ) ;
hr = _asMin/60; min = _asMin%60 ;
};
friend ostream &operator<<(ostream &out, const Time &t2);
friend istream &operator>>(istream &in, Time &t2);
Time operator++(int); //postfix increment
Time& operator++(); //prefix increment
int getTmin(){return hr*60 + min;}
// etc
private:
int min;
int hr;
// int count;
};
Time Time::operator++(int)
{
Time old = *this;
*this = Time( ( getTmin() + 1 ) % Time::MINUTES_PER_DAY );
return old;
}
Time& Time::operator++()
{
*this = Time( ( getTmin() + 1 ) % Time::MINUTES_PER_DAY );
return *this;
}
ostream &operator<<(ostream &out, const Time& t2 )
{ return out << t2.hr << ' ' << t2.min ; }
istream &operator>> ( istream &in, Time& t2 )
{
int hr, min ;
if( ( in >> hr >> min ) &&
( hr >= 0 && hr < 24 ) && ( min >= 0 && min < 60 ) )
{
t2.hr = hr ;
t2.min = min ;
}
else in.clear( ios::failbit ) ; // set stream to failed state
return in ;
}
int main(void)
{
Time time;
cout << "Enter time :" ;
cin >> time;
cout << time++ << '\n' ;
cout << time << '\n' ;
cout << ++time << '\n' ;
cout << time << '\n' ;
/*
Time time;
cout << "Enter time :" ;
cin >> time;
cout << time++ << '\n' ;
cout << ++time << '\n' ;
*/
system("PAUSE");
return(0);
}
Answer> when i enter a time say : 12:05 it's giving me zeroes
the code as it is will work as expected if you enter 12 05 (with white space(s) between 12 and 5).
if you enter 12:05, the input will fail (and the stream will be set to a bad state) because:
a. in >> hr >> min will extract 12 from the input buffer and place the value in the member hr.
b. the input buffer now contains :05
c. the attempt to read min fails because : is not a valid character in an integer.
if you want to accept input as hh:mm, modify the stream extraction operator accordingly:
#include <iostream>
#include <stdexcept>
#include <iomanip>
using namespace std;
...
istream &operator>> ( istream &in, Time& t2 )
{
int hr, min ;
char seperator ;
if( ( in >> hr >> seperator >> min ) && ( seperator == ':' ) &&
( hr >= 0 && hr < 24 ) && ( min >= 0 && min < 60 ) )
{
t2.hr = hr ;
t2.min = min ;
}
else in.clear( ios::failbit ) ; // set stream to failed state
return in ;
}
...
it is a good idea to have output to be symmetric with input.
so modify the the stream insertion operator ( #include <iomanip> )to:
ostream &operator<<( ostream &out, const Time& t2 )
{
return out << setw(2) << setfill('0') << t2.hr
<< ':' << setw(2) << setfill('0') << t2.min ;
}
system("PAUSE"); is avoidable.
to see why and for an alternative see:
http://en.allexperts.com/q/C-1040/2008/12/compilation-error.htm