9.IO库

IO库设施:

· istream(输入流)类型,提供输入操作;

· ostream(输出流)类型,提供输出操作;

  • cin, 一个istream对象,从标准输入读取数据;
  • cout, 一个ostream对象,通过用于输出程序错误消息,写入到标准错误;
  • cerr, 一个ostream对象, 通常用于输出程序错误消息,写入到标准错误;
  • >>运算符,用于从一个istream对象读取输入数据;
  • <<运算符,用于向一个ostream对象写入输出数据;
  • getline函数,从一个给定的istream读取一行数据,存入一个给定的string对象中。

一、IO类

iostream定义了用于读写流的基本类型,fstream定义了读写命名文件的类型,sstream定义了读写内存string对象的类型。

头文件类型
iostream

istream,wistream从流读取数据

ostream,wostream向流写入数据

iostream,wiostream读写流

fstreamifstream,wifstream从文件读取数据

ofstream,wofstream向文件写入数据

iostream,wiostream读写文件

sstream

istringstream,wistringstream从string读取数据

ostringstream,wostringstream向string写入数据

stringstream,wstringstream读写string

 IO类型间的关系

概念上,设备类型和字符大小都不会影响要执行的IO操作。标准库使得能忽略这些不同类型的流之间的差异,这是通过继承机制实现的。

1.1 IO对象无拷贝或赋值

不能拷贝和对IO对象进行赋值:

ofstream out1, out2;
out1 = out2; // 错误:不能对流对象赋值
ofstream print(ofstream); // 错误:不能初始化ofstream参数
out2 = print(out2); // 错误:不能拷贝流对象
1.2 条件状态

IO操作与生俱来的问题就是可能发生错误。一些错误是可恢复的,而其他错误则发生在系统深处,已经超出了应用程序可以修复的范围。下表列出了IO类所定义的一些函数和标志,帮助访问和操纵流的条件状态:

                                                                        IO库条件状态
strm::iostate是一种机器相关的类型,提供了表达条件状态的完整功能

strm::badbit用来指出流已崩溃

strm::eofbit用来指出流到达了文件结束
strm::goodbit()用来指出流未处于错误状态。此处保为零
s.eof()若s的eofbit置位,则返回true
s.fail()若s的failbit或badbit置位,则返回true
s.bad()若s的badbit置位,则返回true
s.good()若s处于有效状态,则返回true
s.clear()若流s中所有条件状态位复位,将流的状态设置位有效。返回void
s.clear(flags)根据给定的flags标志位,将流s中对应条件状态位复位。flage的类型为iostate,返回void
s.setstate(flags)根据给定的flags标志位,将流s中对应条件状态位置位
s.rdstate()返回流s的当前条件状态,返回值类型为iostate

查询流的状态

IO库定义了一个与机器无关的iostate类型,提供了表达流状态的完整功能。还定义了4geiostate类型的constexpr值表示特定的位模式。

  • badbit表示系统级错误,如不可恢复的读写错误。通常情况下,一旦badbit被置位,流就无法再使用了。
  • 在发生可恢复错误后,failbit被置位,如期望读取数值却读出了一个字符等错误。
  • 如果到达文件结束位置,eofbit和failbit都会被置位。
  • goodbit的值为0,表示流未发生错误。
  • 如果badbit、failbit和eofbit任何一个被置位,则检测流状态的条件会失败。

标准库还定义了一组函数来查询标志位的状态。有good,bad,fail,eof四个。

管理条件状态

流对象的rdstate成员返回一个iostate,对应流当前的状态,setstate操作给定条件置位,表示发生了对应错误。clear()清除所有错误标志位。

//记住cin的当前状态
auto old_state = cin.rdstate(); //记住cin的当前状态
cin.clear(); // 使cin有效
process_input(cin); // 使用cin
cin.setstate(oldstate); // 将cin置为原有状态

// 复位failbit和badbit,保持其他标志位不变
cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit);
1.2 管理输出缓冲

每个输出流都管理一个缓冲区,用来保存程序读写的数据。

导致缓冲刷新的原因有很多:

  • 程序正常结束,作为main函数的return操作的一部分,缓冲刷新被执行;
  • 缓冲区满时,而后新的数据才能继续写入缓冲区;
  • 我们可以使用操作符如endl来显示刷新缓冲区;
  • 在每个输出操作之后,可以用操作符unitbuf设置流的内部状态,来清空缓冲区。默认情况下,对cerr的内容都是立即刷新;
  • 一个输入流可能被关联到另一个流。这种情况下,当读写被关联的流时,关联到的流的缓冲区会被刷新。

刷新输出缓冲区

cout<<"hi"<<endl; // 输出hi和一个换行,然后刷新缓冲区
cout<<"hi"<<flush; // 输出hi,然后刷新缓冲区,不附加任何额外字符
cout<<"hi"<<ends; // 输出hi和一个空字符,然后刷新缓冲区

unitbuf操作符

如果想在每次输出操作后都刷新缓冲区,可以使用unitbuf操作符,他告诉流在接下来的每次写操作之后都进行一次flush操作。而nounitbuf操纵副则重置流,使其恢复:

cout<< unitbuf; // 所有输出操作后都会立即刷新缓冲区
// 任何输出都立即刷新,无缓冲
cout<<nounitbuf; // 回到正常的缓冲方式

关联输入和输出流

tie有两个重载的版本,一个不带参数,返回指向输出流的指针。第二个版本接受一个指向ostream的指针将自己关联到此ostream。即x.tie(&o)将流x关联到输出流o。

二、文件输入和输出

                                                                        文件模式
in                                  以读方式打开
out                                以写方式打开

app                               每次写操作前均定位到文件末尾

ate                                打开文件后立即定位到文件末尾
trune                             截断文件
binary                            以二级制方式进行IO

 指定文件模式有如下限制:

  • 只可以对ofstream或fstream对象设定out模式;
  • 只可以对ifstream或fstream对象设定in模式;
  • 只有当out也被设定时才可设定trunc模式;
  • 只要trunc没被设定,就可以设定app模式;
  • 默认情况下。即使没有指定trunc,以out模型打开的文件也会被截断;
  • ate和binary模式可用于任何类型的文件流对象,且可以与其他任何文件模式组合使用。
2.1 文件输入
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    fstream in;
    in.open("1", iso::in);
    if(! in.is_open())
    {
        cout<<"文件不存在"<<endl;    
    }
    /*
    第一种
    char buf[1024] = {0};
    while(in >> buf)
    {
        cout << buf << endl;
    }
    */
    /*
    第二种
    char buf[1024] = {0};
    while(in.getline(buf, sizeof(buf)))
    {
        cout<<buf<<endl;
    }
    */

   /*
    第三种
    string buf;
    while(getline(in, buf))
    {
        cout << buf << endl;
    }
    */
    in.close();
}
2.2 文件输出
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    ostream out;
    out.open("1", ios::out); // 写入文件,但会把文件中的覆盖掉
    // out.open("1", ios::out | ios::app); 写入,从文件末开始
    out << "111"<<endl;
    // ...
    out.close();
}

三、string流

相当于把string当成一个IO流操作。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值