第八章:标准 IO 库

来源:互联网 发布:风险矩阵分析图 编辑:程序博客网 时间:2024/06/03 15:53

参考资源:( http://www.cnblogs.com/kingcat/archive/2012/05/09/2491847.html )

C++ 的输入/输出由标准库提供。

标准库IO 的继承,使类有相同的接口,但是也是错误发生的根源。(一些错误可恢复;一些错误则发生在系统底层,而在程序修正范围之外)

iostream 为内置类型对象提供了输入输出支持,类的设计者也可以通过运算符重载机制扩充 iostream 库,使其支持自定义类型的输入输出操作。

1.OO之标准库


                                简单的 iostream 继承图:

*函数有基类类型的引用形参时,可以给函数传递其派生类型的对象。三种类型流:控制台、磁盘文件和字符串流(对内存读写)。

支持国际字符(wchar_t):头文件相同,所有类都加上 "w" 前缀。

IO 对象不能复制、赋值:

    1.不支持复制------->不能存储在 vector(或其他)容器

    2.形参、返回类型不能为流类型。对 IO 对象读写会改变它的状态,故引用必须是 非const 的。

2.条件状态(condition state)

        

/********* 流状态查询、控制 **********/#include <iostream>using namespace std;int main(){int ival;while (cin >> ival, !cin.eof()){if (cin.bad())         // input stream is corrupted; bail outthrow runtime_error("IO stream corrupted");if (cin.fail()) {                        // bad inputcerr<< "bad data, try again";       // warn the usercin.clear(istream::goodbit);        // reset the streamcin.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); // ignore bad inputcontinue;                            // get next input}else{cout << cin << endl;break;}// ok to process ival}return 0;}

/******* 条件状态下的访问 *********/istream::iostate old_state=cin.rdstate();cin.clear();process_input();  // use cincin.clear(old_state); // now reset cin to old state

多种状态的处理:is.setstate( ifstream::badbit | ifstream::failbit | ... ); 与二进制位按位或处理。

3.输出缓冲区的管理

缓冲区被刷新:

1.程序正常结速时,将清空所有输出缓冲区。

2.在一些不确定的时候,缓冲区可能已经满了,这种情况下,缓冲区将会在写入下一个值之前刷新缓冲区。

       cout<<"Hi!"<<endl; //插入换行符,并刷新缓冲区

       cout<<"Hi!"<<ends; //插入空格字符null,并刷新缓冲区

       cout<<"Hi!"<<flush; //仅仅刷新缓冲区,不插入任何其他字符

3.用操纵符(endl, ends,flush)显式地刷新缓冲区:

4.用unitbuf操纵符设置流的内部状态,则流在每次输出操作执行完都清空缓冲区,恢复系统管理缓冲区刷新方式方式用nounitbuf。

     cout<<unitbuf<<"first"<<"second"<<"third"<<nounitbuf; 

       等价于:

     cout<<"first"<<flush<<"second"<<flush<<"third"<<flush;

5.使用tie函数将输出流与输入流关联起来,当输入流与输出流绑定在一起的时候,任何输入操作都将首先刷新其输出流关联的缓冲区。( 此处不太懂:内容来自 primer )

tie 函数可用 istream 或 ostream 对象调用,使用一个指向 ostream 对象的指针形参。调用 tie 函数时,将实参流绑在调用该函数的对象上。如果一个流调用 tie 函数将其本身绑在传递给 tie 的 ostream 实参对象上,则该流上的任何 IO 操作都会刷新实参所关联的缓冲区。

cin.tie(&cout);   // illustration only: the library ties cin and cout for us 
ostream *old_tie = cin.tie(); 
cin.tie(0); // break tie to cout, cout no longer flushed when cin is read 
cin.tie(&cerr);   // ties cin and cerr, not necessarily a good idea!
    // ... 
cin.tie(0);       // break tie between cin and cerr 
cin.tie(old_tie); // restablish normal tie between cin and cout

一个 ostream 对象每次只能与一个 istream 对象绑在一起。如果在调用 tie 函数时传递实参 0,则打破该流上已存在的捆绑。

#include<fstream>#include<iostream>using namespace std;int main(){ofstream outfile("C:\\Users\\liyangguang\\text.txt");cin.tie(&outfile); //若注释,则直到文件流结束才写入文件outfile<<"A ordinary day!";int i;cin>>i;//system("pause");outfile.close();//system("pause");return 0;}
4.文件的输入和输出 

定义自己的文件流对象:绑定在文件上。

fstream 还定义自己的两个新操作:open 和 close, 以及形参为要打开文件名的构造函数。

流初始化1.

void open(const char *filename, openmode mode); 

void close()// 关闭流并不能改变流对象的内部状态。


cout ,cin 分别是 istream,ostream 类的对象。

因为 cout, cin 指向的是标准设备(显示器屏幕,键盘),所以它在 iostream 头文件中作为全局对象进行定义。但是文件设备不是标准默认设备,所以它在 fstream 头文件中是没有预先定义的全局对象,我们必须自己定义一个对象。例如:要以文件作为设备向文件输出信息,那么就应该使用 ofstream 类。

ofstream类的默认构造函数原形为:  

流初始化2. 

ofstream::ofstream(const char *filename,int mode = ofstream::out(ios::out),int openprot = filebuf::openprot); 
  filename:   文件名
  mode:   打开的文件模式
  prot:    打开文件的属性

 其中 mode 和 openprot 这两个参数的可选项表见下表:
mode属性表( 模式是文件的属性 )
   in           打开文件做读操作
   out         打开文件做写操作
   app        在每次写之前找到文件尾( append )
   ate         打开文件后立即将文件定位在文件尾
   trunc      打开文件时清空已存在的文件流( 如果文件存在,把文件长度设为0 )
   binary     以二进制模式进行 IO 操作

   可以用把以上属性连接起来
openprot属性表:
  0:普通文件,打开访问
  1:只读文件
  2:隐含文件
  4:系统文件

文件模式组合:


ofstream file("example.bin", ofstream::out | ofstream::app | ofstream::binary); 

       // 等价于

ofstream file ;

 file.open("example.bin",ofstream::out | ofstream::app | ofstream::binary) ;

5.字符串流

stringstream 对象的使用:

#include<sstream>#include<iostream>using namespace std;int main(){string line,word;while(getline(cin,line)){istringstream stream(line); // bind to stream to the line we read cout<<line<<endl;while(stream>>word) // read a word from linecout<<word<<endl;}}

转换\格式化:

#include<sstream>#include<iostream>using namespace std;int main(){int val1=512,val2=1024;ostringstream format_message;format_message<<"val1 = "<<val1<<"\n"          <<"val2 = "<<val2<<"\n";string s=format_message.str();cout<<s;istringstream input_istring(format_message.str());string s2;input_istring>>s2>>val1>>s2>>val2;cout<<val1<<" "<<val2<<endl;cout<<s2<<endl;return 0;}


原创粉丝点击