我刚刚想起了文档。 std::istream::getline():
如果函数没有提取字符(例如,如果 count
这意味着在输入超过 10 个字符(包括 EOL)后,std::cin 处于失败状态。因此,如果不对此做出反应,就无法提取更多输入。
您可以通过std::istream::fail() 进行检查。
要清除失败状态,可以使用std::istream::clear()。
在准备 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
Live Demo on coliru