input date

verify that the input is right

Page 1 of 1

9 Replies - 2202 Views - Last Post: 23 February 2010 - 05:34 AM Rate Topic: -----

#1 Slavik  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 14
  • Joined: 21-February 10

input date

Posted 21 February 2010 - 09:02 AM

Hi!

I am writing to you because I've been stuck for some time with input/output operators (>> and << respectively).

What I'm trying to do is the same as the GNU implementation to objects of std, for example std::complex<num type>, but with dates with format yyyy-mm-dd. So the code I typed looks like this:

istream& operator>>(istream& is, date& d)
/*
* Input formats for a date: yyyy-mm-dd
*
* operator>>(istream&, date&) is assumed to set the stream state
* appropriately when reading the date.
*/
{
  int y = 0000, m = 00, d = 00;
  int num,year,month,day = 0;
  is >> y >> num;  
  if (num == ’-’)    // year format correct
  {
    is >> m >> num;
    if (num == ’-’)   // month format correct
    {
      is >> d >> num;
      if (num == ’-’)  // day format correct
      {
        date = 
      }
      else 
      {
        // format error, set the stream state to ’fail’
        is.setstate(ios_base::failbit);
      }
    }
    else 
    {
      // format error, set the stream state to ’fail’
      is.setstate(ios_base::failbit);
    }    
  }
  else 
  {
    // format error, set the stream state to ’fail’
    is.setstate(ios_base::failbit);
  }

  return is;
}


I guess my problem (ok, one of them ;) ) is actually with the sentence

  is >> y >> num;
  if (num == ’-’)
  ...



which has been adapted from the GNU's implementation for complex numbers mentioned above (actually, the whole structure for this has been adapted from it)

is >> im >> c;
if (c == ’(’) 
...



To be honest, I don't understand how does it work, and googling I only see definitions "this is this", but not "it works like this, it should be used like that because...". When input is text i find it easy to control and manipulate, but the problem is that i don't know what lies behind this way of coding, and i don't like at all when i don't know what i'm manipulating with my hands (which in c/c++ i believe is mandatory)

I guess it gets the content in the stream 'is', then checks that its format is like 'im' (in my example, m), and outputs it to 'c' (in my example, num).

Then, I guess, it checks that the next element in 'is' is the char '(' (in my example, the hyphen '-', used as separator). Then, if everything went right, it calls the date constructor and sends it the data.

Is it correct? Anyway, should you have any suggestion about my code, or about a more suitable way of solving the issue, please let me know. Thank you in advance!

Regards,

Slavik.

Is This A Good Question/Topic? 0
  • +

Replies To: input date

#2 Paul-  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 61
  • View blog
  • Posts: 260
  • Joined: 11-December 09

Re: input date

Posted 21 February 2010 - 10:19 PM

Try declaring variable num as a character, not integer.
  int y = 0000, m = 00, d = 00;
  int year,month,day = 0;
  char num;
  is >> y >> num;  
  if (num == ’-’)    // year format correct
...


Was This Post Helpful? 1
  • +
  • -

#3 Plus  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 41
  • View blog
  • Posts: 414
  • Joined: 24-November 08

Re: input date

Posted 22 February 2010 - 12:07 AM

if you take input as a "string",

then you check for the form [ <4 digits> '-' <2 digits> '-' <2 digits> ]

if verified use sscanf(...) to extract numbers


int year,day,month;
char * input;

input = scanf();

if(Check(input)) // function Check checks the form 0000-00-00
{
     sscanf(input, "%d-%d-%d", &year, &day, &month);
}




:: simple ...
Was This Post Helpful? -1
  • +
  • -

#4 Slavik  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 14
  • Joined: 21-February 10

Re: input date

Posted 22 February 2010 - 04:09 AM

@Plus: thanks for your suggestion but I would like to stick to c++; c is will always be there as a last resource, but I won't give up yet :P

@Paul: Ok so I see what you mean. With that code the input format is checked. So now the thing is that if the format is correct, I need to save it as an int. I tried something like this:

  int y = 0000, m = 00, d = 00;
  int year, month, day = 0;
  string input;
  is >> y >> input >> year;
  if (input == ’-’)    // year format correct
  ...



But then the compiler says:


date_test.cc:41: error: expected primary-expression before ‘)’ token


Line 41 is the last one of the code above (the if sentence)


Note that I need the string input to check the separator '-', but the rest (year,month,day), have to be saved as int's


Any clue about this? Thank you!

Regards,

Slavik.

This post has been edited by Slavik: 22 February 2010 - 04:10 AM

Was This Post Helpful? 0
  • +
  • -

#5 carltech  Icon User is offline

  • What did you call me?
  • member icon

Reputation: 28
  • View blog
  • Posts: 997
  • Joined: 19-October 07

Re: input date

Posted 22 February 2010 - 04:28 AM

you can use getline with '-' as a delimiter and then convert to numbers.

This post has been edited by carltech: 22 February 2010 - 04:29 AM

Was This Post Helpful? 0
  • +
  • -

#6 Paul-  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 61
  • View blog
  • Posts: 260
  • Joined: 11-December 09

Re: input date

Posted 22 February 2010 - 11:02 AM

View PostSlavik, on 22 February 2010 - 03:09 AM, said:

@Paul: Ok so I see what you mean. With that code the input format is checked. So now the thing is that if the format is correct, I need to save it as an int. I tried something like this:

  int y = 0000, m = 00, d = 00;
  int year, month, day = 0;
  string input;
  is >> y >> input >> year;
  if (input == ’-’)    // year format correct
  ...



The declaration has to be "char" (single character) not "string".
Was This Post Helpful? 1
  • +
  • -

#7 Slavik  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 14
  • Joined: 21-February 10

Re: input date

Posted 23 February 2010 - 03:42 AM

I've been trying different things, and I think I almost got it.

So what I do is I set my function as a friend of Date class:


//date.h


using namespace std;


namespace cpp_3 {
  class Date {
    
    friend istream& operator>> (istream& is, Date& d);
    ...




And then my function looks like this:



istream& operator>> (istream& is, Date& d)
/*
* Input formats for a date: yyyy-mm-dd
*
* operator>>(istream&, date&) is assumed to set the stream state
* appropriately when reading the date.
*/
{
  char input;
  is >> d.year;
  if (input == '-')    // year format correct
  {
    is >> d.month;
    if (input == '-')   // month format correct
    {
      is >> d.day;
    }
    else 
    {
      // format error, set the stream state to ’fail’
      is.setstate(ios_base::failbit);
    }    
  }
  else 
  {
    // format error, set the stream state to ’fail’
    is.setstate(ios_base::failbit);
  }

  return is;
}





I think this solution looks so much simple and just good, that I think with some fixing it should work pretty well. The thing now is that the compiler doesn't let my function access the private members of the date class, even with the friendship thing (see first code above):

date.h: In function ‘std::istream& operator>>(std::istream&, cpp_lab3::Date&)’:                              
date.h:26: error: ‘int cpp_lab3::Date::year’ is private                                                      
date_test.cc:38: error: within this context                                                                  
date.h:27: error: ‘int cpp_lab3::Date::month’ is private                                                     
date_test.cc:41: error: within this context                                                                  
date.h:28: error: ‘int cpp_lab3::Date::day’ is private                                                       
date_test.cc:44: error: within this context    




Also, in the main program that I use as tester:


int main() 
{
    // Check input and output of dates. Uncomment the following when you 
    // have added operator>> and operator<<.
 
    bool cont = true;
    while (cont) {
        cout << "Type a date: " << flush;
        Date aDate;
        cin >> aDate;            // <---------- HERE! <------------
        if (cin.eof())
            cont = false;
        else if (! cin.good()) {
            cout << "Wrong input format" << endl;
            // restore stream state and ignore the rest of the line
            cin.clear();
            cin.ignore(10000, '\n');
        }
        else
            cout << "Output: " << aDate << endl;
    }






Compiler says that there's an ambiguous overload for ‘operator>>’ in ‘std::cin >> aDate


Any suggestion? Thank you!

This post has been edited by Slavik: 23 February 2010 - 03:50 AM

Was This Post Helpful? 0
  • +
  • -

#8 Martyn.Rae  Icon User is offline

  • The programming dinosaur
  • member icon

Reputation: 540
  • View blog
  • Posts: 1,406
  • Joined: 22-August 09

Re: input date

Posted 23 February 2010 - 04:13 AM

I know I am coming into this topic perhaps a bit late, but I would have looked at this problem in a slightly different way. We have a class called istream, which almost does everything that we want except deal with dates. So I would create a new class derived from istream, call it say mystream. So you would have:

class mystream : public istream {
};



I have made the derivation public, so that my code can access all the routines in istream and the extra routines in mystream.

Now, I want an overloaded operator >>, so here it is:

class mystream : public istream {
    public:
        mystream& operator>> (Date& d); 
};



Now comes the implementation part:

mystream& mystream::operator>> (Date& d) 
/* 
* Input formats for a date: yyyy-mm-dd 
* 
* operator>>(date&) is assumed to set the stream state 
* appropriately when reading the date. 
*/ 
{ 
  char input; 
  istream::operator >>(d.year);
  if (input == '-')    // year format correct 
  { 
    istream::operator >>(d.month); 
    if (input == '-')   // month format correct 
    { 
      istream::operator >>(d.day); 
    } 
    else  
    { 
      // format error, set the stream state to ’fail’ 
      istream::setstate(ios_base::failbit); 
    }     
  } 
  else  
  { 
    // format error, set the stream state to ’fail’ 
	  istream::setstate(ios_base::failbit); 
  } 
 
  return *this; 
}



This code compiles under MS VC++ 2008, and I have no reason to suspect it will not compile on other compilers. I have not tested the code, but I see no reason why it should not work.

NOTE: The calling of the derived class operator>> functions. This looks somewhat odd I know, but it is exactly what you must do to call such beasts.

Hope this is helpful.
Was This Post Helpful? 1
  • +
  • -

#9 Slavik  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 14
  • Joined: 21-February 10

Re: input date

Posted 23 February 2010 - 05:25 AM

Ok already solved! I just misplaced definitions. Anyway, thanks!

Btw, should someone be interested in it, here's the final code:


date.h

using namespace std;


namespace cpp_lab3 {
  class Date {
    
    friend istream& operator>> (istream& is, Date& d);
    friend ostream& operator<< (ostream& os, Date& d);
    
    public:
      Date();                      // today's date
      Date(int y, int m, int d);   // yyyy-mm-dd
      int getYear() const;         // get the year
      int getMonth() const;        // get the month
      int getDay() const;          // get the day
      void next();                 // advance to next day
      istream& operator>> (Date& d);
      ostream& operator<< (Date& d);
    private:
      int year;                    // the year (four digits)
      int month;                   // the month (1-12)
      int day;                     // the day (1-..)
      static int daysPerMonth[12]; // number of days in each month
    };
}





date.cc

  istream& operator>> (istream& is, Date& d)
  /*
  * Input formats for a date: yyyy-mm-dd
  *
  * operator>>(istream&, date&) is assumed to set the stream state
  * appropriately when reading the date.
  */
  {
    char input;
    is >> d.year;
    is >> input;
    if (input == '-')    // year format correct
    {
      is >> d.month;
      is >> input;
      if (input == '-')   // month format correct
      {
        is >> d.day;
      }
      else 
      {
        // format error, set the stream state to ’fail’
        is.setstate(ios_base::failbit);
      }    
    }
    else 
    {
      // format error, set the stream state to ’fail’
      is.setstate(ios_base::failbit);
    }
    return is;
  }

  ostream& operator<< (ostream& os, Date& d)
  {
    return os << d.year << "-" << d.month << "-" << d.day;
  }


}







date_test.cc

int main() 
{
    // Check input and output of dates. Uncomment the following when you 
    // have added operator>> and operator<<.
 
    bool cont = true;
    while (cont) {
        cout << "Type a date: " << flush;
        Date aDate;
        cin >> aDate;
	cont = false;
        if (cin.eof())
           cont = false;
        else if (! cin.good()) {
            cout << "Wrong input format" << endl;
            // restore stream state and ignore the rest of the line
            cin.clear();
            cin.ignore(10000, '\n');
        }
        else
            cout << "Output: " << aDate << endl;
    }
}




Enjoy!

This post has been edited by Slavik: 23 February 2010 - 05:29 AM

Was This Post Helpful? 0
  • +
  • -

#10 Slavik  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 14
  • Joined: 21-February 10

Re: input date

Posted 23 February 2010 - 05:34 AM

@Martyn.Rae

Nice code! Looks much more beautiful than mine. Once I finish other assignments I'll play with it. Thanks!
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1