C++—— 恢复状态标志和清理缓存(以标准库输入流std::cin输入整数时死循环为例)
来源:互联网 发布:淘宝类似威廉的男装店 编辑:程序博客网 时间:2024/05/21 22:35
C++—— 恢复状态标志和清理缓存(以标准库输入流std::cin输入整数时死循环为例)
标准库输入流std::cin输入整数时死循环
本文,主要解决用标准库输入流std::cin输入整数的时候,如果误输入了字符产生的死循环问题。
这也许是C++灵活的背后,给程序员所带来的一些问题。
解决方法比较简单,代码如下:
#include<iostream>#include <limits>// 带容错功能的控制台整数输入函数int input_int(){ int n; // 处理输入字符时的死循环异常 while (!(std::cin >> n) || std::cin.peek() != '\n') { std::cin.clear();// 恢复状态标志 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');// 略过缓存 std::cerr << "输入数据错误,请重新输入:" << std::endl; } return n;}int main(){ std::cout << input_int() << " ,输入成功结束" << std::endl; system("pause"); return 0;}
先搞清楚几个重要的函数:cin.fail(), cin.bad(), cin.good(), cin.clear(), cin.ignore()等。
在搞清楚了这几个函数后,对cin输入操作的错误处理就有了比较深的了解了。
用getline()读取字符串超长,所以导致出现异常,所以会导致后面的 cin>>ch 语句没有执行。
那我们利用前面学习的clear()函数来强制重置错误标志,看看会出现什么情况呢?
#include <iostream>using namespace std;int main (){char ch, str[20];cin.getline(str, 5);cout<<"flag1:"<<cin.good()<<endl; // 查看goodbit状态,即是否有异常cin.clear(); // 清除错误标志cout<<"flag1:"<<cin.good()<<endl; // 清除标志后再查看异常状态cin>>ch; cout<<"str:"<<str<<endl;cout<<"ch :"<<ch<<endl;return 0;}
测试输入:
12345[Enter]
输出:
flag1:0 // good()返回false说明有异常
flag2:1 // good()返回true说明,clear()已经清除了错误标志
str:1234
ch :5
丢弃输入缓冲区中的字符
这个函数用来丢弃输入缓冲区中的字符,第一参数定义一个数,第二个参数定义一个字符变量。下面解释一下函数是怎样执行的:函数不停的从缓冲区中取一个字符,并判断是不是_Delim,如果不是则丢弃并进行计数,当计数达到_Count退出,如果是则丢弃字符退出。例:cin.ignore(5, ‘a’); 函数将不断从缓冲区中取一个字符丢弃,直到丢弃的字符数达到5或者读取的字符为’a’。下面我们看个程序例子:
#include <iostream>using namespace std;int main (){cin.ignore(5, 'a');return 0;}
测试一输入:
c[enter]
c[enter]
c[enter]
c[enter]
c[enter]
程序结束。
【分析】程序开始时缓冲区是空的,cin.ignore()到缓冲区中取数据,没有则请求从键盘输入,每次从键盘输入一个字符,如果不是’a’则丢弃,所以该测试中共输入了5次,直到计数达到5。
测试二输入:
c[enter]
c[enter]
a[enter]
程序结束。
【分析】前面两个字符不是’a’丢弃且计数没达到5,第三次输入为’a’, 丢弃该字符程序结束!
丢弃一个字符:
#include <iostream>using namespace std;int main(){char c1, c2;cin.get(c1); cin.ignore(); // 用该函数的默认情况,丢弃一个字符,即上次输入结束的回车符cin.get(c2);cout<<c1<<" "<<c2<<endl; // 打印两个字符cout<<(int)c1<<" "<<(int)c2<<endl; // 打印这两个字符的ASCII值return 0; }
测试一输入:
a[Enter]
b[Enter]
输出:
a
b
97 98
【分析】这样程序就正常了!
清空整个缓冲区:
其实该函数最常用的方式是这样的,将第一个参数设的非常大,将第二个参数设为’/n’,这样就可以缓冲区中回车符中的所有残留数据,因为一般情况下前面输入残留的数据是没有用的,所以在进行新一次输入操作前将缓冲区中所有数据清空是比较合理。
如:cin.ignore(1024, ‘/n’);
或者:cin.ignore(std::numeric_limits::max(), ‘/n’);
- C++—— 恢复状态标志和清理缓存(以标准库输入流std::cin输入整数时死循环为例)
- 用 cin 输入整数死循环问题
- cin标准输入流错误清理
- cin标准输入流错误清理
- 用文件结束符(Ctrl+Z)结束元素输入时不要忘记将流cin恢复为有效状态
- 输入任意整数中1出现的次数(以-1为结束标志)
- scanf和cin输入类型不匹配时造成的死循环问题
- C++—— cin输入流详解
- c++ cin一个整数 输入其它字符产生死循环错误的解决方法。
- C语言标准输入缓存区清理方法列表
- 从键盘输入一组非0整数,以输入0为结束标志,求这组整数的平均值,并统计其中正数和负数的个数。(根据循环变量的初值、终值无法判断出循环次数时建议使用while或do while语句完成)。
- 输入流cin的状态
- C++ Cin输入数字时 输入字母 Cin状态出错
- scanf/cin输入若干整数以回车结束,并存储,用C/C++实现
- 整型变量输入为字符时死循环解决
- 【C++】输入流cin方法
- cin标准输入流错误处理
- cin标准输入流的错误处理
- element清空单个输入框
- 2的次幂表示
- 安装ros遇到的问题:有未满足的依赖关系......
- Linux--驱动之设备树 学习之路
- SSH环境搭建
- C++—— 恢复状态标志和清理缓存(以标准库输入流std::cin输入整数时死循环为例)
- 51Nod 1381 硬币游戏
- reduce 方法
- 单点故障
- C语言经典算法(一)——求最大公约数的四种方法
- hbase 集群(完全分布式)方式安装
- java.lang.NoSuchFieldError: USE_DEFAULTS
- 【第十一周】673. Number of Longest Increasing Subsequence
- VS项目属性的一些配置项的总结(important)