Member Avatar for j.kelly

I am relatively new to C++ and am a bit unsure why the following function doesn't work.

/*********************************************************
* GetDate: Takes a string to be displayed to the user 
* and returns a CTime object. Returns NULL if an invalid 
* date is entered
*********************************************************/
CTime GetDate(string requestString)
{
  string inputStr;
  int day;
  int month;
  int year;

  cout << requestString << endl;
  cout << "Enter Date In The Format dd/mm/yyyy" << endl;
  cin >> inputStr;

  day = atoi(inputStr.substr(0, 2).c_str());
  month = atoi(inputStr.substr(3, 2).c_str());
  year = atoi(inputStr.substr(6, 4).c_str());

  CTime *date;

  try
  {
    date = new CTime(year, month, day, 0, 0, 0);
  }
  catch(...)
  {
    date = NULL;
  }

  return *date;
}

The function crashes if and invalid date is input (32/12/2000) even though I have used a try catch statement.

Could somebody explain why this doesn't work please?

Thanks
James

If the date is invalid you do this:

date = NULL;

Then you proceed to do this:

return *date;

That would be dereferencing a null pointer, which is illegal and highly likely to crash your program. Of course, that entire function is one big red flag. Perhaps this would be a little better:

CTime *GetDate ( const string& requestString )
{
  string inputStr;
  int day, month, year;

  cout << requestString << endl;
  cout << "Enter Date In The Format dd/mm/yyyy: " << endl;

  if ( !getline ( cin, inputStr ) )
    throw runtime_error ( "Line input error" );

  istringstream iss ( inputStr );

  if ( !( iss>> day >> month >> year ) )
    throw runtime_error ( "Formatted input error" );

  return new CTime ( year, month, day, 0, 0, 0 );
}

Instead of catching the exception in GetDate, require the highest level possible to catch exceptions and deal with them accordingly. It's obvious that GetDate has no idea how to handle an exception, so there's no point in catching it here. And of course, it's a good idea to look for errors in your input as well. Include <stdexcept> for runtime_error, and instead of using ... as your catch expression, derive a more precise exception from std::exception or one of it's children and use that instead:

class InvalidDateException: public runtime_error {
public:
  InvalidDateException ( const string& msg ): runtime_error ( msg ) {}
};
Member Avatar for j.kelly

Thanks for the help

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.