Я согласен с Андерсом Абелем и Йоханнесом Шаубом; Я также думаю, что не может быть гарантировано, что в случае ошибки принципал останется нетронутым, поэтому вы можете рассмотреть возможность добавления principal=0.0;
в начале цикла.
Кстати, для выполнения такой работы я обычно использую эту функцию шаблона:
template<typename InType> void AcquireInput(std::ostream & Os, std::istream & Is, const std::string & Prompt, const std::string & FailString, InType & Result)
{
do
{
Os<<Prompt.c_str();
if(Is.fail())
{
Is.clear();
Is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Is>>Result;
if(Is.fail())
Os<<FailString.c_str();
} while(Is.fail());
}
template<typename InType> InType AcquireInput(std::ostream & Os, std::istream & Is, const std::string & Prompt, const std::string & FailString)
{
InType temp;
AcquireInput(Os,Is,Prompt,FailString,temp);
return temp;
}
Первая перегрузка может быть предпочтительнее, если вы хотите избежать копирования, вторая может быть более удобной для встроенных типов.
Примеры использования:
//1st overload
double aDouble;
AcquireInput(cout,cin,"Please insert an integer: ","Invalid value.\n",aDouble);
//2nd overload (more convenient, in this case and in general with POD)
double aDouble=AcquireInput(cout,cin, "Please insert an integer: ","Invalid value.\n");
В вашем случае вы можете изменить свой код следующим образом:
double principal=0.0;
const char * errMsg="Plese enter a number greater than zero. Please try again.\n";
while(principal<=0.0)
{
principal=0.0;
principal=AcquireInput(cout,cin,"Please enter the loan principal: ",errMsg);
if(principal<=0.0)
cout<<errMsg;
}