Я только что вспомнил док.из std::istream::getline()
:
Если функция не извлекает никаких символов (например, если число <1), выполняется settate (failbit). </p>
Это означает, что после ввода более 10 символов (включая EOL) std::cin
находится в состоянии сбоя.Следовательно, никакие входные данные не могут быть извлечены, не реагируя на это.
Вы можете проверить это с помощью std::istream::fail()
.
Чтобы очистить состояние отказа, *Можно использовать 1019 *.
При подготовке MCVE я обнаружил еще одну слабость:
Смешивание std::istream::getline()
с операторами входного потока >>
требует особого внимания, поскольку
getline()
читает до конца строки, но operator>>
читает пробелы (включая конец строки) перед фактическим значением.
Следовательно,ignore()
следует использовать после ошибки в getline()
, чтобы отбросить остаток строки, но ignore()
следует использовать всегда после std::cin >> students[i].age
, чтобы использовать конец строки, по крайней мере.
Итак, я пришелс этим:
#include <iostream>
int main()
{
const unsigned N = 3;
const unsigned Len = 10;
struct Student {
char name[Len];
int age;
};
Student students[N];
for (unsigned i = 0; i < N; ++i) {
std::cout << "Enter name of student " << i + 1 << ": ";
std::cin.getline(students[i].name, Len);
if (std::cin.fail()) {
std::cerr << "Wrong input!\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
std::cout <<"Enter age of student : " << i + 1 << " ";
std::cin >> students[i].age;
if (std::cin.fail()) {
std::cerr << "Wrong input!\n";
std::cin.clear();
}
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
// check read
std::cout << "\nStudents:\n";
for (unsigned i = 0; i < N; ++i) {
std::cout << i + 1 << ".: "
<< "name: '" << students[i].name << "'"
<< ", age: " << students[i].age << "\n";
}
}
Ввод / вывод:
Enter name of student 1: Johann Sebastian
Wrong input!
Enter age of student 1: 23
Enter name of student 2: Fred
Enter age of student 2: 22
Enter name of student 2: Fritz
Enter age of student 2: 19
Students:
1.: name: 'Johann Se', age: 23
2.: name: 'Fred', age: 22
3.: name: 'Fritz', age: 19
Живая демонстрация на coliru