C++----IO类

C++的IO类不支持拷贝和赋值操作,通常通过引用传递。每个输出流都有缓冲区,可通过endl等操纵符管理。文件流对象能与文件关联,读写操作需要注意错误检测和关闭文件。string流如istringstream用于从字符串读取,ostringstream则用于构建字符串。
摘要由CSDN通过智能技术生成

为了支持不同的IO处理操作,C++定义了一系列IO类型,如下表

头文件类型
iostreamistream,从流读取数据; ostream,向流写入数据; iostream,读写流
fstreamifstream,从文件读取数据; ofstream,向文件写入数据; fstream,读写文件
sstreamistringstream,从string读取数据;ostringstream,向string写入数据;stringstream,读写string

IO对象无拷贝或赋值

我们不能拷贝或对IO对象赋值:

ofstream out1,out2;
out1 = out2;    //wrong
ofstream print(ofstream);   //wrong,不能初始化ofstream参数
out2 = print(out2);     //wrong:不能拷贝流对象

由于不能拷贝IO对象,因此我们也不能讲形参或返回类型设置为流类型。进行IO操作的函数通常以引用方式传递和返回流。读写一个IO对象会改变其形态,因此传递和返回的引用不能是const的。

管理输出缓冲

每个输出流都管理一个缓冲区,用来保存程序读写的数据。例如,如果执行下面的代码

os<<"please enter a value:";

文本串可能立即打印出来,也可能保存在缓冲区中,稍后打印。导致缓冲刷新的原因有:

  1. 程序正常结束,作为main函数的return操作的一部分,缓冲刷新被执行。
  2. 缓冲区满时
  3. 使用操纵符如endl等,显式刷新
  4. 使用操纵符unitbuf设置
  5. 一个输出流可能关联到另一个流。在这种情况下,当读写被关联的流时,关联到的流的缓冲区会被刷新。例如,在默认情况下,cin和cerr都关联到cout。
cout<<"hi!"<<endl;      //输出hi!和一个换行,然后刷新缓冲区
cout<<"hi!"<<flush;     //输出一个hi!,然后刷新缓冲区,不附加任何额外字符
cout<<"hi!"<<ends;      //输出hi!和一个空字符,然后刷新缓冲区


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

使用文件流对象

ifstream in(ifile);         //构造一个ifstream,并打开给定文件
ofstream out;           //输出文件流为关联到任何文件

如果我们定义了一个空文件流对象,可以随后调用open来将它与文件关联起来

out.open(ifile+".copy");

如果调用open失败,failbit会被置位。因为调用open可能失败,进行open是否成功的检测通常是个好习惯:

if(out)

还要记得关闭

in.close();
in.open(ifile+"2");

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

string流

使用istringstream

考虑一个例子,记录员工信息,有些人的电话可能有多个:

morgan 20151123 12354234
drew 23141334
lee 1356782211 1238412334 1231249999

文件中每条记录都以一个人名开始,后面跟随一个或多个电话号码。我们首先定义一个简单的类来描述输入数据:

struct PersonInfo{
    string name;
    vector<string> phones
}

我们开始读取数据

string line,word;       //分布保存来自输入的一行和单词
vector<PersonInfo>people;       //保存来自输入的所以记录
//逐行从输入读取数据,直至cin遇到文件尾(或者其他错误)
while(getline(cin,line)){
//getline从保准输入读取整条记录。如果getline调用成功,
//那么line中将保存着从输入文件而来的一条记录。
PersonInfo info;
istringstream record(line);//将记录绑定到刚读入的行,这样就可以用输入运算操作符读取元素啦
record>>info.name;
while(record>>word)
    info.phones.push_back(word);
people.push_back(info);
}

从一个string中读取数据,当string中的数据全部读出后,同样会触发“文件结束”信号,在record上的下一个输入操作会失败。

使用ostringstream

类似,用<<

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值