I'm trying to overload the >>operator for a Date class in c++ but the it goes in infinite loop when the run goes into the first if statement, can you please help me?
//operator
istream& operator >>(istream& is,CustomDate& d){
int day,month,year;
char ch1,ch2;
string test;
is>>skipws>>day>>ch1>>month>>ch2>>year;
if(!is){
is.clear(ios_base::failbit);
return is;
}
if(ch1!='/' || ch2!='/')
error("invalid date input");
d = CustomDate(day,month,year);
return is;
}
This is the function that calls it
CustomDate Menu::inputDate(){
CustomDate date;
cout<<"Input your departure date"<<endl;
cin>>date;
if(!cin){
error("invalid date format");
}
return date;
}
And this is the the loop that calls the function
do{
try{
date = inputDate();
validDate = true;
}
catch(runtime_error& e){
cout<<"Date format not valid! must input as dd/mm/yyyy!"<<endl;
validDate = false;
}
}while(!validDate);
//customdate constructor
CustomDate::CustomDate()
:day(1),month(1),year(2012){}
CustomDate::CustomDate(int day, int month, int year)
:day(day),month(month),year(year){
if(day<0 || day>30)
error("Error: Date constructor");
if(month<0 || month>12)
error("Error: Date constructor");
if(year<0)
error("Error: Date constructor");
}
Your code has a number of errors. The
do ... try ... catch
loop is potentially an infinite loop, and it is also potentially incorrect.You'll get an infinite loop if you have enabled exceptions on your input stream and the parse in the stream extraction statement fails in the overloaded
operator>>
. Your code never resets the stream, so once you get a parse error your code is stuck in a loop. Forever.What if you don't have exceptions enabled and inputs are mangled enough to make the stream extraction statement mark the stream as "bad" in some way? Exceptions aren't enabled, so no exception is thrown. Your code (the then branch if the if statement immediately after the stream extraction call) will execute. This too doesn't throw an exception. The
do ... try ... catch
will succeed. Here your code erroneously accepts bad input as valid.I would rework your example as it relies on being able to input multiple items, namely int char int char int. I would input one string. Then use a stringstream to parse the date and check its format.
So it might be something like:
Im not sure if this would fix any infinite loop, but it might be a better way to go for checking the input.
As I said in a comment:
Rather than throwing an exception from the stream extraction operator just the failbit if it can't extract integers or the separator characters are wrong (also try using more whitespace to help make the code more readable):
Then handling failed extractions in
inputDate