You are here:

C++/still on my increment operator

Advertisement


Question
QUESTION: 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  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


vijayan

Expertise

my primary areas of interest are generic and template metaprogramming, STL, algorithms, design patterns and c++11. i would not answer questions about gui and web programming.

Experience

about 15 years or so

Education/Credentials
post graduate engineer

©2016 About.com. All rights reserved.