Каждый раз, когда в этой функции возникает ошибка с типом ввода, она автоматически устанавливает значение * _cost в 0. Почему это происходит?
void Item::setCost(string input){
float entered;
istringstream stin;
stin.str(input);
if(!(stin >> entered)){
do{
cout << "invalid input" << endl;
stin.clear();
getline(cin, input);
stin.str(input);
*_cost = entered;
}
while(!(stin >> entered));
}
else{
*_cost = entered;
}
}
Я использую функцию в своей основной функции следующим образом:
istringstream stin;
string input;
cout << "enter cost" << endl;
getline(cin, input);
items[i]->setCost(input);
Вы устанавливаете *_cost
значение, которое из-за оператора if ВСЕГДА будет обязательно неправильным значением. *_cost = entered
будет выполняться ТОЛЬКО, когда программа переходит через код "неверный вход". Программа только печатает "недопустимый вход", когда введенный не является юридическим значением. Поэтому параметр _cost может быть установлен только на недопустимое значение.
Чтобы решить вашу проблему, *_cost = entered
после цикла do-while.
Я не уверен, почему вы не просто используете std :: cin для прямого чтения данных, а не для преобразования стандартного ввода в экземпляр std :: string, а затем в istringstream.
Вам нужно перенести первый *_cost = entered
из do.. while
блок станет первым после него. Сделав это, вы увидите, что дополнительный рефактор полезен, хотя и не требуется.
while(!(stin >> entered))
{
cout << "invalid input" << endl;
stin.clear();
getline(cin, input);
stin.str(input);
}
*_cost = entered;
при выполнении *_cost = entered;
в вашем коде entered
неверный.
Я только что скорректировал ваш код с вашим первоначальным намерением
bool Item::setCost(string input) {
bool ret_val = true;
float entered = 0.0;
istringstream stin;
stin.str(input);
while ( !(stin >> entered) ) { // loop till you read a valid input
if ( !stin.rdbuf()->in_avail() ) {
ret_val = false;
break;
}
}
*_cost = entered;
return ret_val;
}
stin.rdbuf()->in_avail()
может использоваться для получения количества доступных символов, готовых для чтения из строкового потока, вы можете использовать это, чтобы проверить, является ли ваш stringstream "пустым".
Например, если вы хотите извлечь float из istringstream, но вы получите что-то еще (условие отказа), а затем посмотрите, есть ли какие-либо оставшиеся символы (например, числовые), вы можете проверить, является ли stin.rdbuf()->in_avail() == 0
.