C++ IO流学习笔记

IO 库类型和头文件:

头文件        类型

iostream       istream,wistream 从流读取数据

ostream,wostream 向流写入数据

iostream,wiostream 读写流

fstream       ifstream,wifstream 从文件读取数据

ofstream,wofstream 向文件写入数据

fstream,wfstream 读写文件

sstream       istringstream,wistringstream 从 string 读取数据

ostringstream,wostringstream 向 string 写入数据

stringstream,wstringstream 读写 string

条件状态:

strm::iostate   strm是指一种IO类型,iostate是一种机器相关的类型,提供表达条件状态的完整功能。
strm::badbit   标志流已崩溃,致命的输入/输出错误,无法挽回
strm::failbit   标志IO操作失败了,非致命的输入/输出错误,可挽回
strm::eofbit   标志达到文件结尾
strm::goodbit  流未出现错误状态,此值保证为0
s.eof()     若流s的eofbit置位,则返回true
s.fail()     若流s的failbit或badbit置位,则返回true
s.bad()     若流s的badbit置位,则返回true
s.good()    若流s处于有效状态,则返回true
s.clear()    将流的所有条件复位,状态设置为有效,返回void
s.clear(flags)  根据flags标志位,将s中对应条件状态复位,flags类型为strm::iostate。返回void
s.setstate(flags) 根据flags标志位,将s中对应条件状态置位,flags类型为strm::iostate。返回void
s.rdstate()    返回流的当前条件状态,返回类型为strm::iostate

状态位

1.4种条件状态
badbit 用来指出流已经崩溃,属于系统级错误,如不可恢复的读写错误。

failbit 表示一个io操作失败了,比如读取数字却读取的是字符,这是可以恢复的

eofbit 用来表示文件达到文件结尾,这也是可以恢复的

goodbit 表示流的状态正常

注意的是,一但流发生错误,其上后续的io操作都会失败,只有流属于无错状态时,我们才可以用来读取数据,写入数据。

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a,b;
    cin>>a;
    cout<<cin.good()<<endl;//如果流正常返回1
    cout<<cin.fail()<<endl;  //failbit(输入错误,可以恢复)或者badbit(系统崩溃),则被置位。
    cout<<cin.rdstate()<<endl;//流正常返回1
    getchar();
    cin>>b;//如果上次输入失常,这里就不能使用了。
    return 0;
}
管理流当前状态
#include<bits/stdc++.h>
using namespace std;
int main(){
    auto x=cin.rdstate();//rdstate返回当前状态,
    cin.clear();//将状态恢复(可以在发生了可恢复错误的时候使用)
    int a;
    cin>>a;
    cin.setstate(x);//将cin变成原来状态
    return 0;
}

检查输入流当前的状态

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a,b=3;
    cin>>a;
    cin>>b;//不可用
    if(cin.rdstate() == ios::goodbit)cout<<"this input is true"<<endl;
    else if(cin.rdstate() == ios::failbit)cout<<"输入类型错误,可以通过清除缓冲区挽回、"<<endl;
    cout<<b<<endl;
    cin>>b;
    cout<<b<<endl;
    return 0;
}
#include <iostream>
using namespace std;
int main(void){
    int a;
    cin >> a;
    cout << cin.rdstate() << endl;
    cin.clear(ios::goodbit);//使cin有效
    cout << cin.rdstate() << endl;
    return 0;
}
管理输出缓冲:

每个输出流都管理一个缓冲区,用来保存程序读写的数据:
os << "please enter a value: ";
文本串可能立即打印出来,也有可能被操作系统保存在缓冲区,随后再打印。
会导致刷新缓冲区的原因:

  • 程序正常结束,作为 main 函数的 return 的一部分,缓冲刷新被执行。
  • 缓冲区满,需要刷新缓冲区,而后新的数据才能写入。
  • 使用操纵符:endl 来显示刷新缓冲区。
  • 每个输出操作后,可以用操作符unitbuf设置流的内部状态,来清空缓冲区。默认情况下,cerr 是设置 unitbuf 的,因此写到 cerr 中的数据都是立即刷新的。
  • 一个输出流被关联到另一个流,此时,当读写被关联的流时,关联到流的缓冲区会被刷新。默认cin 和 cerr 都关联到 cout,因此读 cin 或写 cerr 都会导致 cout 的缓冲区被刷新。

endl  换行并刷新缓冲区;
ends  插入一个空字符并刷新缓冲区;
flush  仅刷新缓冲区;

#include <iostream>
using namespace std;
int main(void){
    cout << unitbuf;//所有输出操作后都会立即刷新缓冲区
    //任何输出都立即刷新,无缓冲
    for(int i=1;i<=50000;i++)cout<<i;
    cout << nounitbuf;//回到正常的缓冲方式
    for(int i=1;i<=50000;i++)cout<<i;
    //令人疑惑的是为什么两种方式的时间差不多,有时候正常的换缓冲方式更慢。
    return 0;
}
刷新缓冲区的方式
#include <iostream>
using namespace std;
int main(void){
    cout<<"ghq"<<ends;//输出空格并刷新缓冲区
    cout<<"ghq"<<endl;//输出换行并刷新缓冲区
    cout<<"ghq"<<flush;//刷新缓冲
    return 0;
}
关联输入和输出流:

当一个输入流关联到一个输出流时,任何试图从输入流读取数据的操纵都会先刷新关联的输出流。标准库将 cout 和 cin 关联到一起,因此:cin >> val;导致 cout 的缓冲区被刷新。

  • tie是将流关联到另一个流的函数,C++中定义如下:
    tie 有两个重载版本:一个版本不带参数,返回指向输出流的指针。如果本对象关联到一个输出流,则返回的就是指向这个流的指针,如果对象未关联到流,则返回空指针。tie 的第二个版本接受一个指向 ostream 的指针,将自己关联到 ostream。即,x.tie(&o) 将流 x 关联到输出流 o。
    我们既可以将一个 istream 对象关联到另一个 ostream,也可以将一个 ostream 关联到另一个 ostream:
#include <iostream>
using namespace std;
int main(void)
{
    cin.tie(&cerr);//直接将cin由和cout关联改成和cerr关联
    cin.tie(&cout);//将输入流cin关联到输出流cout
    ostream *old_tie = cin.tie(nullptr);//cin不再与其他流关联
    cin.tie(&cerr);//将cin关联到cerr,读取cin会刷新cerr而非cout
    cin.tie(old_tie);//重建cin和cout之间的关联
    return 0;
}

注意:每个流同时最多关联到一个流,但多个流可以同时关联到一个 ostream。

·
·
·
·
·
靡不有初鲜克有终。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值