您的位置:首页 > 编程语言 > C语言/C++

本科教育忽略的黄金C++<1> IO类

2016-02-15 15:23 519 查看
本章节属于C++标准库内容

C++语言不直接处理输入输出,而是通过一族定义在标准库中的类型来处理IO。这些类型支持:

从设备读取数据、向设备写入数据的IO操作,设备可以是文件、控制台窗口。

相关的IO库设施

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

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

cin,一个istream对象,从标准输入读取数据。

cout,一个ostream对象,从标准输出写入数据。

cerr,一个ostream对象,通常用于输出程序错误消息,写入到标准错误。

运算符>>:用来从一个istream对象读取输入数据。

运算符<<:用来向一个ostream对象写入输出数据。

getline函数:从一个给定的istream中读取一行数据,存入一个给定的string对象中。

1、IO类

标准库定义了其他一些IO类型。

(头文件)iostream:定义了读写流的基本类型。

(类型)

istream,wistream从流读取数据。

ostream,wostream从流写入文件。

iostream,wiostream读写流。

(头文件)fstream:定义了读写命名文件的类型。

(类型)

ifstream,wifstream从文件中读取数据。

ofstream,wofstream向文件写入数据。

fstream,wfstream文件读写流。

(头文件)sstream:定义了读写内存String对象的类型。

istringstream,wistringstream:从string读取数据。

ostringstream,wostringstream:向string写入数据。

stringstream,wstringstream:读写string。

注:为了支持使用宽字符的语言,标准库定义了一组类型和对象来操纵wchar_t类型的数据。

IO类型间的关系

标准库使我们能够忽略不同类型流之间的差异,通过继承机制实现(设备类型和字符大小不会影响我们要执行的IO操作)。继承机制使我们可以声明一个特定的类继承自另一个类。我们通常可以将一个派生类对象当做基类对象来使用。【ifstream,istringstream继承自istream,那么怎么使用istream对象,对于其派生类对象也可以这么使用】

(1)IO对象五拷贝或者赋值

不能对流对象赋值,不能初始化ofstream参数,不能拷贝流对象。

不能将形参或者返回类型设置为流类型。进行IO操作的函数通常以引用方式传递和返回流。读写一个IO对象会改变其状态,因此传递和返回的引用不能够是const的!!!

(2)条件状态

我们访问和操纵流的条件状态。

strm::iostream: strm是一种IO类型,就是上面列出的相关类(iostream之类的)。iostate是一种机器相关的类型。提供了表达条件状态的完整功能。

对象:

strm::badbit: 指出流已经崩溃。表示系统级别错误,不可恢复的读写错误。一旦置位,那么流就无法使用了。

strm::failbit: 用来指出一个IO操作失败了。发生可恢复错误。

strm::eofbit:指出流到达终点。

strm::goodbit:用来指出流未处于错误状态,此值保证为0。

方法:

s.eof(): 若流s的eofbit置位。则返回true。到达文件结束位置,eofbit,failbit都会被置位。

s.fail():若流s的failbit或者badbit置位,则返回true。

s.bad():若流sbadbit置位,那么返回true。

s.good():若流处于有效状态,返回true。

使用good或者fail是确定流总体状态的正确方法

s.clear():将流s中所有条件状态复位,将流的状态设置为有效。返回void。清除所有错误标志位。

s.clear(flags):根据给定的flags标志位,将流s中对应条件状态复位。flags的类型为strm::iostate。返回void。

s.setstate(flags):根据给定的flags标志位,将流s中对应条件状态位置位。返回void。

s.rdstate():返回流s当前的状态。返回值类型为strm::iostream。

注意:一个流一旦发生错误,其上后续的IO操作都会失败。只有当一个流处于无错误状态时,我们才可以从它读取数据,向它写入数据。(因此代码通常应该在使用一个流之前检查它是否处于良好状态。)

while(cin>>word)
{
//输入成功之后的操作
}


带参数版本的clear使用方法:

用位操作将所需位复位来生成新的状态。

cin.clear(cin.rdstate()&~cin.failbit&~cin.badbit);


(3)管理输出缓冲

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

导致缓冲刷新的原因:

I.程序正常结束。作为main函数的return操作的一部分,缓冲刷新被执行。

II.缓冲区满了。使用endl来显式刷新缓冲区。

III.可以用操作符unitbuf设置流的内部状态,来清空缓冲区。一般状态下,cerr是设置成unitbuf的,因此写到cerr当中的内容都是立即被刷新的。unitbuf告诉刘在接下来的每次写操作之后都要进行一次flush操作。而nounitbuf操作符则会重置流,使其恢复使用正常的系统管理的缓冲区刷新机制。

IV.一个输出流可能被关联到另一个流当中。当读写被关联的流时,关联到的流的缓冲区会被刷新。

刷新输出缓冲区

flush:刷新缓冲区,但是不输出任何额外字符。

ends:向缓冲区插入一个空字符,然后刷新缓冲区。

<如果程序异常终止,输出缓冲区是不会被刷新的。>

关联输入和输出流

交互式系统通常应该关联输入流和输出流。

tie可以完成相关的任务。

无参数版本:返回指向输出流的指针。如果本对象关联到一个输出流,则返回的就是指向这个流的指针。

带参数版本(接受一个指向ostream指针)将自己关联到此ostream。

彻底解开流的关联,传递空指针。

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

2、文件输入输出

关于文件相关的对象和方法:

fstream ftrm;


创建一个未绑定的文件流。fstream是头文件fstream当中的一个类型。

fstream ftrm(s);


创建一个fstream并且打开一个名为s的文件。s可以使string类型,或者是指向C风格字符串的指针。默认的mode依赖于fstream的格式。

fstream ftrm(s,mode);


指定mode格式。

fstrm.open(s);


打开名为s的文件并且将文件和fstrm绑定。s可以使string类型,或者是指向C风格字符串的指针。默认的mode依赖于fstream的格式。

fstrm.close();


关闭与fstrm绑定的文件。返回void。

fstrm.is_open();


返回一个bool值,指出与fstrm关联的文件是否成功打开且尚未关闭。

(1)使用文件流对象

定义一个空文件流对象,随后调用open来将他与文件关联起来。

如果调用open失败,failbit会被置位。调用open可能会失败,所以进行open检验是一个好习惯:

ifstream in(infile);
ofstream out;
out.open(infile+".copy");
if(out)
{
//open成功之后使用文件
}


一旦文件流打开,就保持与对应文件的关联。实际上对一个已经打开的文件流调用open会失败。并且会导致failbit被置位。随后的试图使用文件流的操作都会失败。为了将文件流关联到另外一个文件,必须首先关闭已经关联的文件。一旦文件成功关闭,才可以打开新的文件。

当一个fstream对象离开作用域时,与之关联的文件会自动关闭。

当一个fstream被销毁时,close会自动调用。

(2)文件模式

每个流都有吧一个关联的文件模式。用来指出如何使用文件:

in:以读方式打开。

out:以写方式打开。

trunc:截断文件。

app:每次写操作前都定位到文件末尾。

ate:打开文件后立刻定位到文件末尾。

binary:以二进制方式进行IO。

文件模式限制:

只可以对ofstream或者fstream对象设定out模式。

只可以对ifstream或fstream对象设定in模式。

只有当out也被设定时才可以设定trunc模式。

只要trunc没被设定,就可以设定app模式。在app模式之下,即使没有显示指定out模式,文件也是以输出方式打开。

默认情况下,即使我们没有指定trunc,以out模式打开的文件也会被截断。为了保留以out模式打开的文件的内容,我们必须同时指定app模式。

ate和binary模式可以用于任何类型的文件流对象,而且可以与其他任何文件模式组合使用。

以out模式打开文件会丢弃已有数据[/b]

默认情况下,当我们打开一个ofstream的时候,文件的内容会被丢弃。阻止一个ofstream清空给定文件内容的方法是,同时指定app模式。

每次调用open的时候都会确定文件模式!!

通常情况下,out模式意味着同时使用trunc模式。

3、string流

相关的对象和方法:

sstream strm;


strm未绑定的stringstream对象。

sstream strm(s);


strm是一个sstream对象,保存strings的一个拷贝。

strm.str();


返回strm所保存的string的拷贝。

strm.str(s);


将string s拷贝到strm中。返回void。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ IO流