【c++】流状态的查询和控制

简介:

源自

c++primer 4th, 248页

代码

复制代码
#include <iostream>
#include <limits>
#include <stdexcept>

using namespace std;
int main()
{
    int ival;
    while(cin >> ival, !cin.eof())
    {
        cout << "hello:" << cin.fail() << endl;
        if(cin.bad())
            throw runtime_error("IO stream is corrupted!");
        if(cin.fail())
        {
            cerr << "bad data, try again." << endl;
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            continue;
        }
    } 
}
复制代码

几个地方

1. 逗号表达式

首先计算每一个操作数,然后返回最右边的操作数最为整个操作的结果,因此while(cin >> ival, !cin.eof())看重的只是!cin.eof(),而对前边的cin>>val不关心。

 

2. 条件状态

流状态由eof, bad, fail, good指示,如果eof, bad, fail任何一个为true那么流监测状态为错误状态;相反都为false,则good为true.

其中badbit标志着系统级的故障,是不可回复的,如果流出现这种情况,流通常就不能继续使用了;failbit标志着是可恢复的,可以修正。eofbit在遇到文件结束符时设置,此时还设置了failbit.

clear()和setstate()用于改变条件成员的状态。clear()将条件重设为有效状态(eof, bad, fail置为false;good置为true),setstate()把某个特定的流设为有效状态。

 

3. cin

程序的输入都建有一个缓冲区,即输入缓冲区。一次输入过程是这样的,当一次键盘输入结束时会将输入的数据存入输入缓冲区,而cin函数直接从输入缓冲区中取数据。正因为cin函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,cin函数会直接取得这些残留数据而不会请求键盘输入.

注意

处理间隔符号(严格讲是重定向符号>>, <<):遇到Enter、Space、Tab键,会自动当作间隔符号(当然,会把他们读入到输入缓冲区,但是处理的时候会丢弃掉)。

cin >> val 的返回值是cin, 即左值(同样cout<<val返回左值cout),这样就可以把cin >> val1; cin >> val2 合并为cin>>val1>>val2;

 

4. ignore函数

作用:提取输入字符并丢弃他们。

函数原型:istream& ignore (streamsize n = 1, int delim = EOF)

             读取到前n个字符或在读这n个字符进程中遇到delim字符就停止,把读取的这些东西丢掉。

案例

复制代码
#include <iostream>
#include <fstream>
#include <sstream>
#include <limits>
#include <stdexcept>
#include <typeinfo>

using namespace std;

int main()
{
    int val1, val2;
    while(1)
    {
        cin >> val1;
        cin.ignore(5, '9');
        cin >> val2;
        cout << "val1:" << val1 << endl;
        cout << "val2:" << val2 << endl;
    }
}
复制代码

运行结果

注意:如果读了n个字符,后面这个正好是停止字符,那么都读出来干掉(例子的最后一个)!

numeric_limits<streamsize>::max() 此时读取的为最大长度,已经没有界限,只能靠停止符终止。本例中为‘\n’,即从回车后开始读取

 

5. 为何必须有ignore()函数

cin.clear()把failbit位清零,但是错误的输入(不是指回车)还是在缓冲区,每次一读错误就做相同的处理,如果没有ignore(),那么当输入错误时,就会无限循环。并且还不是简单的cin.ignore(),默认的为ignore(1, '\n'),这样会导致输入几个错误的字符循环几次,例如

复制代码
    while(cin >> val, 1)
    {
        cout << "hello " << endl;
        cin.clear();
        cin.ignore();
    }
复制代码




本文转自jihite博客园博客,原文链接:http://www.cnblogs.com/kaituorensheng/p/3463415.html,如需转载请自行联系原作者


相关文章
|
5月前
|
Ubuntu C++
如何在命令行流畅查询 C++ 文档?
不知道大家有没有同样的经历,在搬砖酣畅淋漓的时候,每一次切屏都是对思路的严重干扰,特别是切了好几屏都找不到浏览器的时候,简直要爆炸。
29 0
|
5月前
|
算法 测试技术 C#
C++二分查找算法:包含每个查询的最小区间
C++二分查找算法:包含每个查询的最小区间
|
4月前
|
安全 程序员 C++
C++中的类型查询:探索typeid和type_info
C++中的类型查询:探索typeid和type_info
50 1
|
5月前
|
域名解析 C++
C++ Qt开发:QHostInfo主机地址查询组件
在Qt网络编程中,QHostInfo是一个强大而灵活的组件,用于获取有关主机的信息,包括主机名、IP地址和域名解析等。通过支持异步查询的机制,它能够在后台获取主机信息,避免阻塞主线程,同时通过信号-槽机制提供查询结果。其多主机查询、可靠的错误处理和与网络环境的适应性,使其成为处理网络应用中主机信息获取的理想选择。
83 6
C++ Qt开发:QHostInfo主机地址查询组件
|
10月前
|
SQL 监控 C#
C/C++ 运用WMI接口查询系统信息
Windows Management Instrumentation(WMI)是一种用于管理和监视`Windows`操作系统的框架。它为开发人员、系统管理员和自动化工具提供了一种标准的接口,通过这个接口,可以获取有关计算机系统硬件、操作系统和应用程序的信息,以及对系统进行管理和控制的能力。WMI允许通过编程方式查询系统信息、监视性能、执行管理任务等。它提供了一种统一的方式来访问和管理Windows操作系统的各个方面,而无需了解底层实现细节。通过WMI,可以使用各种编程语言(如C#、VBScript、PowerShell等)来执行诸如查询系统信息、监控性能、配置系统设置等任务。
111 0
C/C++ 运用WMI接口查询系统信息
|
5月前
|
算法 测试技术 C++
C++二分查找算法:包含每个查询的最小区间
C++二分查找算法:包含每个查询的最小区间
C/C++ 库函数查询工具MSDN
当我们学习C/C++ 总会用到库函数,而面对陌生的函数时,我们就要去查询它的作用,参数,头文件,返回值等等。但是我们在查询它们的用用法时可能会耗费时间和精力,所以我将为大家提供一个好用的查询软件MSDN(注:不需要联网使用)
C/C++ 库函数查询工具MSDN
C++编程练习:设计一个银行账户类,包含户名、帐号以及当前余额属性,并且能完成开户、存款、取款和查询余额等行为。
C++编程练习:设计一个银行账户类,包含户名、帐号以及当前余额属性,并且能完成开户、存款、取款和查询余额等行为。
C++编程练习:设计一个银行账户类,包含户名、帐号以及当前余额属性,并且能完成开户、存款、取款和查询余额等行为。
|
Rust 算法 安全
【算法】1476. 子矩形查询(java / c / c++ / python / go / rust)
请你实现一个类 SubrectangleQueries ,它的构造函数的参数是一个 rows x cols 的矩形(这里用整数矩阵表示),并支持以下两种操作: updateSubrectangle(int row1, int col1, int row2, int col2, int newValue) 用 newValue 更新以 (row1,col1) 为左上角且以 (row2,col2) 为右下角的子矩形。 getValue(int row, int col) 返回矩形中坐标 (row,col) 的当前值。