cin.getline 如果用户输入的输入大于 char 数组,则跳过输入的提醒

cin.getline skips the reminder of the input if the user enters larger input than the char array

我正在尝试将数据输入到结构数组中,其中包含一个 char 数组成员和一个 int 成员,如下所示:

int main(){
    typedef struct {
        char name[10];
        int age;
    }Student;
    Student students[3];
    for (i=0;i<N;i++){
        cout<<"\n Enter name of student : "<< i+1<<" " ;
        cin.getline(students[i].name, 10);
        cout<<"\n Enter age of student : "<< i+1<<" ";
        cin>>students[i].age ;    
    }

但是如果我输入的名称超过 10 个字符(用户可能会这样做),那么其余的输入命令将被忽略。

我尝试添加 cin.ignore() 但没有帮助。

我尝试将 gets(students[i].name);fflush(stdin); 一起使用,但这也无济于事。

我无法使用 std::string。有什么建议么?

我刚刚想起了文档。的 std::istream::getline()

If the function extracts no characters (e.g. if count < 1), setstate(failbit) is executed.

即输入超过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";
  }
}

Input/Output:

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