Я пытаюсь определить, вводит ли пользователь что-то, кроме символа, и, в частности, что они вводят только m или s. См. Код ниже.
Заметка:
filingStatus
- char
do
{
cout << "Please enter your filing status (s for single, m for married)" << '\n';
cin >> filingStatus;
if (cin.fail())
{
cin.clear();
dataTest = 1;
cout << "Error, please enter a valid input!" << '\n';
double dummyDouble;
cin >> dummyDouble;
if (cin.fail())
{
cin.clear();
cin >> dummyString;
}
}
else
{
if (filingStatus == 'm' || filingStatus == 's')
{
dataTest = 0;
}
else
{
cout << "Error, please enter either m or s!" << '\n';
dataTest = 1;
}
}
} while (dataTest == 1);
Вот проблема, если я, например, вводю 1000, вход не прерывается. Он вместо этого сохраняет 1 в символе, а так как 1 не является ни m, ни S, он снова циклытся, затем он снова ставит циклы 0, ставит еще 0 и т.д.
Я понял, что это не сработает, когда увидит, что целое число хранится в символе, но, очевидно, оно не терпит неудачу.
Мой вопрос:
Вход не прерывается, потому что '1'
является символом. Цифры - это подмножество символов.
Читайте в std::string
. Затем проверьте, состоит ли эта строка из одного символа из вашего желаемого диапазона.
Обратите внимание, однако, что чтение в строку с использованием >>
останавливается в первом пробеле. Чтобы предотвратить это и прочитать всю строку, прочитайте с помощью std::getline()
.
std::string filingStatus ;
while(!(cin >> filingStatus ) || ( filingStatus != "m" && filingStatus != "f") )
{
cin.clear();
std::cout << "Error, please enter either m or s!" << '\n';
};
Один из способов может состоять в том, чтобы изменить fillingStatus
на string
и получить только первый символ этой строки и посмотреть, не сработает ли она или нет.
В качестве альтернативы, когда-то был метод получения ввода символов, getche()
я думаю (прошло много лет с тех пор, как я работал в C++, поэтому не помню точно)... возможно, вы тоже можете это использовать.
благодаря
Поскольку вы только читаете ввод по одному символу за раз, вы по существу не можете сказать, что пользователь имеет больше ввода, и он удерживается, пока вы не прочитаете больше из входного потока.
Использование string
для считывания строки данных за раз и с учетом того, что программа реагирует на эту строку в целом, решит вашу проблему.
Я предполагаю, что fillingStatus
имеет тип char
.
Теперь, даже если вы вводите цифру "1" или "0", она считывается как символ. Следовательно, cin не подводит. Он просто продолжает цикл в соответствии с вашим кодом.
Кроме того, при чтении недопустимого символа вы должны быть осторожны при очистке входного буфера, потому что возвращаемый символ "\n" остается вместе с другими символами в буфере ввода.
Я бы сделал это примерно так:
while ( !(cin >> fillingStatus) || (filingStatus != 'm' && filingStatus != 's') ) {
cout << "Error, please enter either m or s!" << '\n'; // error message
cin.clear(); // clear the error flag
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // ignore all invalid previous input
}