处理方法
为避免错误字符导致输入失败,在输入失败之时,清除错误标志并且忽略错误字符,之后重新输入,直至输入正确为止。
错误用法
使用std::cin.seekg方法移动输入序列指针至序列末尾,代码如下所示:
#include <iostream>
int main()
{
int n;
using std::cin;
while (!(cin >> n)) // 若输入失败
{
cin.clear(); // 清除错误标志
cin.seekg(0, cin.end); // 移动输入序列指针至序列末尾
}
cin.ignore().get(); // 忽略Enter键产生的换行符并等待Enter键以暂停程序
return 0;
}
经测试,在以下两个环境之中,对于默认缓冲区移动输入序列指针失败,而输入流设置失败标志(failbit)。
操作系统 | 编译工具 |
---|---|
Windows 10 | Visual Studio 2017 |
Ubuntu 18.04 | gcc 7.4 |
代码解析
- 第7-11行:若输入整型数字却输入非法字符,输入流设置失败标志,循环条件成立,进而执行循环体。先清除错误标志,再移动输入序列指针,但移动失败,由于输入序列残留非法字符,下一次输入仍失败,从而导致死循环。
正确用法
运用std::cin.ignore方法从输入序列中提取字符并丢弃之,代码如下所示:
#include <limits>
#include <iostream>
int main()
{
int n;
using std::cin;
while (!(cin >> n))
{
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
cin.ignore().get();
return 0;
}
输入流对象std::cin的成员函数ignore用于忽略输入序列剩余字符,直至忽略限定数量的字符,或者遇到分隔字符,出错或者到达序列末尾为止,分隔字符也被忽略。
代码解析
- 第11行:若限定数量是std::numeric_limits<std::streamsize>::max(),则无数量限制。