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
我正在尝试将数据输入到结构数组中,其中包含一个 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