C++流文件的一些基本概念

一. 面向对象的标准库
IO标准库类型和头文件
头文件
iostream istream从流中读取
ostream写到流中去
iostream对流进行读取;从istream和ostream派生而来
fstream ifstream从文件中读取
ofstream写到文件中去,由ostream派生而来
fstream读写文件,由iostream派生而来
sstream istringstream从string对象读取:由istream派生而来
ostreamstream写到string对象中去;由ostream派生而来
stringstream对string对象进行读写;由iostream派生而来
IO类型在三个独立的头文件中定义:iostream定义读写控制窗口的类型,fstream定义读写已命名文件的类型,而sstream所定义的类型则用于读写存储在内存中的string对象。
对istream&进行操作的函数,也可使用ifstream或者istringstream对象来调用。类似的,形参为ostream&类型的函数也可用ofstream或者ostringstream对象调用。因为IO通过继承关联,所以可以只编写一个函数,而将他应用到三种类型的流上:控制台,磁盘文件或者字符串流。
1. 国际字符的支持
除了支持读写是由char类型组成的流外,标准库还定义了一组相关的类型,支持wchar_t类型。每个类都加上w,以此与char类型的版本区分开来。于是,wostream,wistream和wiostream可以从控制窗口读写wchat_t类型的数据。相应的文本输入输出类是wifstream,wofstream和wfstream。同样,wchar_t的读入类型是wcin,标准输出是wcout;而标准错误是wcerr。
2. IO对象不可赋值或复制
由于流对象不能复制,因此不能存储在vector或其他容器中。另外,形参或返回类型不能为流类型。如果需要传递或返回IO对象,则必须传递返回指向该对象的指针或引用。
一般情况下,如果需要对传递IO的对象进行读写,可用非const引用方式传递这个流对象。
二. 条件状态
IO标准库的条件状态
strm::iostate 机器相关的类型名,由各个iostream类定义,用于条件状态
strm::badbit strm::iostate类型的值,用于指出被破坏的流
strm::failbit strm::iostate类型的值,用于指出失败的IO操作
strm::eofbit strm::iostate类型的值,用于指出流已经达到文件结束符。
s.eof() 如果设置了流s的eofbit值,则该函数返回true。
s.fail() 如果设置了流s的failbit值,则返回true。
s.bad() 如果设置了流s的badbit值,则返回true。
s.good() 如果流s处于有效状态,则该函数返回ture。
s.clear() 将s中的所有状态值都重设为有效状态
s.clear(flag) 将流s中的某个指定条件状态设为有效。Flag的类型是
strm::iostate
s.setstate(flag) 给流s添加指定条件,flag的类型是strm::iostate
s.rdstate() 返回流s的当前条件,返回值类型为strm::iostate
流必须处于无错误状态,才能用于输入和输出。检查流是否可用的最简单方法是检查其真值:
if(cin)
//ok, 可以使用cin,它为合法值
while(cin>>word)
//ok.成功读取操作
1. 条件状态
所有流对象都包括一个条件状态成员,该成员分别有setstate和clear操作管理。这个状态成员为iostate类型。这是由各个iostream类分别定义的机器相关类型。该状态成员以二进制的形式使用。
badbit标志着系统级的故障,如无法恢复的读写错误。如果出现了这样的错误,则该流通常就不能在继续使用了。如果出现的是可恢复错误,此时则设置failbit标志,这种导致了failbit的问题是可以修正的。Eofbit实在遇到文件结束符设置的,此时同时还设置了failbit。
流的状态由bad,fail,eof和good操作表示。如果bad,fail或者eof任意一个为ture,则检查流本身将显示该流处于错误状态。类似的,如果这三个条件没有一个为true。则good操作将返回true。
2. 条件状态的访问
rdstate成员函数返回一个iostate类型的值,该值对应于流当前的整个条件状态。
istream::iostate old_state=cin.rdstate();
cin.clear();
process_input():
cin.clear(old_state):
3. 多种状态的处理
常常会出现设置或清楚多个二进制的情况。此时,可以通过多次调用setstate或者clear函数实现。另外一种方法则是安位或操作符来实现。
is.setstate(ifstream::badbit | ifstream::failbit);
三. 输出缓冲区的管理
每个IO对象管理一个缓冲区,用于存储程序读写的数据。
os<<" please enter a value: ";
系统将字符串字面值存储在与流os相关联的缓冲区中,下面几种情况将导致缓冲区的内容被刷新,即写入到真实的输出设备或者文件:
a. 程序正常结束。作为main函数返回工作的一部分,将清空所有输出缓冲区。
b. 在一些不确定到时候,缓冲区可能满了,缓冲区在写入下一个值之前刷新。
c. 用操作符显式的刷新缓冲区,例如行换行符endl。
d. 在每次输出操作执行完后,用unitbuf操作符设置流的内部状态,从而情况缓冲区。
e. 可将输入流和输出流关联起来,在这种情况下,在读输入流时将刷新其关联的输出缓冲区。
1. 输出缓冲区的刷新
除了endl操作符,C++还提供了另外的两个类似的操纵符。第一个是经常使用的flush,用于刷新流,但仍然不再输出中添加任何字符。第二个是比较少用的ends,这个操作在缓冲区中插入空字符null,然后刷新它。
2. unitbuf操纵符
如果需要刷新所有输出,最好使用unitbuf操作符。这个操作符在每次执行完写操作后都刷新流:
cout<< unitbuf <<"first"<<"second"<<nounitbuf;
nounitbuf操纵符将流恢复为正常的,由系统管理的缓冲区刷新方式。
如果程序崩溃了,则不会刷新缓冲区。如果程序不正常结束,输出缓冲区将不会被刷新。
3. 将输入和输出绑在一起
当输入流和输出流绑在一起时,任何读输入流的尝试都将首先刷新其输出流相关联的缓冲区。标准库将count和cin绑在一起。语句:cin>>ival;导致cout关联的缓冲区被刷新。交互式系统通常应确保它们的输入和输出流是绑在一起的。这样做意味着可以保证任何输出,包括给用户的提示,都在试图读之前输出。
Tie函数可以用istream或ostream对象调用,使用一个指向ostream对象的指针形参。调用tie函数时,将实参流绑在调用该函数的对象上,如果一个流调用tie函数将其本身绑定在传递给tie的ostream实参对象时,则该流上的任何IO操作都会被刷新实参所关联的缓冲区。
四. 文件的输入与输出
fstream头文件中定义了三种支持文件IO的类型:
a. ifstream,由istream派生而来。
b. ofstream,由ostream派生而来
c. fstream,由iostream派生而来
fstream类型除了继承下来的行为外,还定义了两个自己的新操作,open和close,以及形参为要打开的文件名的构造函数。fstream,ifstream,ofstreram对象可以调用这些操作,其他的IO类型不能调用。
1. 文件流对象的使用
有两种方式:
a.直接用带参数的够造函数打开一个文件名为string类型的ifile,
ifstream infile(ifile.c_str());
b.使用默认构造函数初始化一个文件流对象,然后调用open函数。
ifstream infile;
infile.open("in");
检查文件是否打开成功,这是一个好习惯:
if(!infile)
{
cerr<<"error: unable to open input file: "<<ifile<<endl;
return -1;
}
将文件流与新文件重新绑定
fstream对象一旦打开,就保持与指定文件相关联。如果要把fstream对象与另一个不同的文件关联,则必须先关闭现在的文件,然后打开另一个文件。
ifstream infile("in");
infile.close();
infile.open("next");
清除文件流的状态
关闭流不能改变流对象的内部状态。如果最后的读写操作失败了,对象的状态保持为错误模式,直到指向clear操作重新恢复流的状态为止。调用clear后,就像重新创建了个对象一样。如果程序员要重用文件流读写多个文件,必须在读另一个文件之前调用clear清除该流的状态。
2. 文件模式
in 打开文件做读操作
out 打开文件做写操作
app 在每次写之前找到文件尾
ate 打开文件后立即定位在文件尾
trunc 打开文件时清空已存在的文件流
binary 以二进制模式进行IO操作
out,trunk,和app模式只能用于指定与offstream或fstream对象关联的文件;in模式只能用于指定与ifstream或fstream对象相关联的文件。所有的文件都可以用ate或binary模式打开。Ate模式只有在打开时有效:文件打开后将定位在文件尾。以binary模式打开的流则将文件以字节的形式处理,不解释流中的字符。
默认时,与ifstream流对象关联的文件将以in模式打开,该模式运行文件做读的操作,与ofstream关联的文件则以out模式打开,使文件可写。从效果来看,为ofstream对象指定了out模式等效于同时指定了out和trunc模式。对于ofstream打开的文件,要保存文件中已存在的数据,唯一方法是显式的指定app模式打开。
a. 对同一文件做输入和输出运算
fstream对象既可读也可写它所关联的文件。Fstream如何使用它的文件取决于打开文件时指定的模式。默认情况下,fstream对象是以in和out模式同时打开。当文件同时以in和out打开时不清空。如果打开fstream所关联的文件时,只用out模式,而不用in模式,则文件清空已存在的数据,如果打开指定了trunc模式,无论是否同时指定了in模式,文件同样会被清空。
b. 模式是文件的属性而不是流属性
只要调用open函数,就要设置文件模式,其模式的设置可以是显式的,也可以是隐式的。如果没有指定文件模式,将使用默认值。
c. 打开模式的有效组合
out ; out | app ; out | trunc ; in ; in | out ; in | out | trunk;
五. 字符串流
istringstream,由istream派生而来,提供读string的功能
ostringstream 由ostream派生而来,提供写string的功能
stringstream 由iostream派生而来,提供读写string的功能
stringstream除了继承基类的操作外,还各自定义一个又string形参的构造函数,这个构造函数将string类型实参复制给stringstream对象。
stringstream特定的操作
stringsteam strm; 创建自由的stringstream对象
stringstream strm(s); 创建存储s的副本的stringstream对象,其中s是string类型的对象。
strm.str(); 返回strm中存储的string类型对象
strm.str(s); 返回string类型的s复制给strm,返回void。
1. stringstream对象的使用
将一个stringstream对象与所读取的行绑定起来,这样只需使用普通的string输入操作符即可读出每行中的单词。
String line, word;
While ( getline(cin, line))
{
istringstream stream(line);
while( stream>>word)
//….
}
2. stringstream提供的转换或格式化
stringstream对象的一个最常用的用法是:需要在多种数据类型之间实现自动格式化使用该类类型。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值