Я использую cin.getline() для хранения пользовательского ввода в массиве символов и пытаюсь проанализировать ввод, чтобы разрешить ввод только чисел от 1 до 4. Все работает нормально при определенных обстоятельствах: правильный ввод вводится с первой попытки, ИЛИ вводятся 2 или менее символов, а после вводится правильный ввод. Пример ниже.
[Expected behavior]
Enter input: 1 [ENTER]
Input accepted
[Expected behavior]
Enter input: rw [ENTER]
Incorrect input. Please try again.
Enter input: 1 [ENTER]
Input accepted
[Unexpected behavior]
Enter Input: rtw [ENTER]
Incorrect input. Please try again.
Enter Input: 1 [ENTER]
Incorrect input. Please try again.
Enter input: 1 [ENTER]
Incorrect input. Please try again.
[This will continue indefinitely]
Я пробовал все, от очистки входного буфера до сброса массива символов до нулевых терминаторов в попытке увидеть, хранит ли он все еще значения из предыдущего ввода (например, в неожиданном поведении, если «tw» каким-то образом все еще был в памяти) . Я думаю, что у меня может быть проблема, похожая на это обсуждение, но я не уверен на 100%. Когда я пытаюсь очистить буфер ввода, он ожидает второго набора ввода, и я не знаю, почему. Когда я печатаю результаты inputLength
после запуска "неожиданного поведения", он показывает, что в массиве все еще есть 2 или 3 символа, когда я ввел только 1. При удалении cin.clear()/cin.ignore() , второй вход не нужен, но тогда происходит описанное выше поведение. Я ценю любую помощь.
Я разместил соответствующий код ниже.
char* ValidateInput() {
const int maxInput = 25;
char userInput[maxInput] = { "\0" };
int inputLength = 0;
bool correctInputBool = false;
while (!correctInputBool) {
// subtract 1 to allow for null terminator at end of array
cin.getline(userInput, (maxInput - 1), '\n');
// I have tried both versions of cin.ignore() below, but neither works
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
//cin.ignore(numeric_limits<streamsize>::max());
// calculate how many characters user entered
inputLength = sizeOfCharArray(userInput, maxInput);
// I do other things here, there isn't a problem with this. For now, assume all 1-character input is acceptable
if (inputLength == 1) {
cout << "Correct input." << endl;
correctInputBool = true;
}
if (!correctInputBool) {
cout << "Sorry, that input is incorrect. Please try again." << endl;
cout << "Please enter a number between 1 and 4." << endl;
}
return userInput;
}
int sizeOfCharArray(char input[], int maxSize) {
// all values in input are set to "\0", so count all characters that are not null
int userSize = 0;
for (int index = 0; index < maxSize; index++) {
if (input[index] != '\0') {
userSize++;
}
}
return userSize;
}
РЕДАКТИРОВАТЬ: я заметил, что когда я ввожу более 3 символов, следующий запуск всегда будет сбрасывать inputLength
на одно значение. Ввод 9 символов уменьшается до 8 при повторном запросе ввода, даже если было введено только 1
.
cin >>
в своем коде так же, какcin.getline()
? Или любые другие форматированные извлечения из этого потока? - person Yksisarvinen   schedule 22.01.2020*"\0"
активирует мои чувства UB (хотя я не уверен в этом на 100%). Вместо этого вы хотели'\0'
(один символ). - person Yksisarvinen   schedule 22.01.2020"\0"
, но я добавил*
после того, как компилятор наорал на меня. Я тоже менял выше. - person   schedule 22.01.2020inputLength
на одно значение. Ввод 9 символов уменьшается до 8 при повторном запросе ввода, даже если было введено только1
. - person   schedule 22.01.2020ValidateInput
отсутствует закрывающая}
. Может быть, это просто неуместная скобка, потому что прямо сейчасwhile (!correctInputBool) {
всегда будет встречаться сreturn userInput;
, поэтому цикл не имеет смысла в этой форме. - person churill   schedule 22.01.2020std::getline
иstd::string
? - person churill   schedule 22.01.2020std::getline
, так иstd::string
, но не могу, так как это домашнее задание. Я вынужден использовать строки в стиле C - person   schedule 22.01.2020