简单的IO类继承层次结构图
简化一下,字母后都省略一个单词stream
很简单的继承关系istream、ostream作为基类
istream 派生出 ifstream、istringstream ; ostream 派生出 ofstream、ostringstream
同时由 istream与ostream 共同派生出 iostream
iotream 派生出 fstream、stringstream
在上述继承关系中,以前加上一个w就是其宽字符的类,eg: wistream、wstringstream
头文件
分别包含在3个头文件中
iostream //定义读写控制窗口的类型
系统已经定义好了8个输入/输出对象、包含 cin、cout、cerr、clog 以及其宽字符的版本wcin等
fstream //定义读写已命名文件的类型
sstream //定义读写存储在内存中string对象的类型
IO对象不可复制或赋值
如果需要传递或返回IO对象,则必须传递或返回指向该对象的指针或引用
eg:
ofstream& print(ofstream &ref);
条件状态与输出缓冲区的管理
对于iostream、fstream、stringstream都适用
流条件状态
strm::iostate //用于定义条件状态
strm::badbit //用于指出被破坏的流,不可恢复(系统级故障)
strm::failbit //用于指出失败的io操作,可恢复
strm::eofbit //用于指出流已经到达文件结束符
eg:
cout << istream::badbit << istream::failbit << istream::eofbit;
//输出421表明二进制分布为111对应上述语句的位值
流方法
s.eof()、s.fail()、s.bad()、s.good()、s.clear()、s.clear(flag)、s.setstate(flag)、s.rdstate()
eg://条件状态的访问
istream::iostate oldState = cin.rdstate();//返回流当前条件状态,返回值类型 strm::iostate
cin.clear();
//process
cin.clear(oldState);
eg://多种条件状态的处理
is.setstate(ifstream::badbit | ifstream::failbit);//设置 ifstream::badbit | ifstream::failbit 条件状态(有效),对应位设置为1,其他默认为0
//process
is.clear(ifstream::badbit | ifstream::failbit);//清除 ifstream::badbit | ifstream::failbit 条件状态(失效),对应位设置为0
eg://输入管理
int iVal;
while(cin >> iVal, ! cin.eof())
{
if(cin.bad)
throw runtime_error("IO stream corrupted!");
if(cin.fail())
{
cerr << "bad data, try again";
cin.clear(istream::failbit);
continue;
}
}
缓冲区管理
输出缓冲区的刷新
flush ends(space,insert a null charater)endl(line,insert a newline)
unitbuf刷新
eg:
cout << unitbuf << "content..." << nounitbuf;
tie输入与输出
eg:
cin.tie(&cout);//这只是演示,标准库已经为我们绑定了 cin 和 cout
ostream *oldTie = cin.tie();//返回一个指向ostream对象的指针
cin.tie(0);//break tie between cin and cout
cin.tie(&cerr);//ties cin and cerr
//process
cin.tie(0);
cin.tie(oldTie);//恢复cin cout绑定
文件输入与输出
文件流对象的使用
两种使用形式
1.文件流构造函数
2.open函数
fstream特有: open、close方法
eg:
ifstream inFile("in.txt");
ofstream outFile;
outFile.open("out.txt");
检查文件打开是否成功
eg:
ifstream inFile;
string ifile("in.txt");
inFile.open(ifile.c_str());//由于历史原因,文件名用C风格字符串
if(! inFile)
{
cerr << "error: unable to open input file: " << ifile << endl;
return -1;
}
文件流的关闭与重新捆绑
eg:
ifstream inFile("in.txt");
inFile.close();
inFile.open("in2.txt");
清除文件流状态
eg:
while(it != files.end())
{
ifstream input(it->c_str());//每次都生成新的流对象,所以input.good()每次都会置为true
if(! input)
break;
while(input >> s)
//process
++it;
}
eg:
ifstream input;//只生成一次流对象
vector<string>::const_iterator it = files.begin();
while(it != files.end())
{
input.open(it->c_str());
if(! input)
break;
while(input >> s)
//process
input.close();
input.clear();//更小心的处理流状态,不然的话下一次迭代不一定成功
++it;
}
文件模式
文件输入与输出的两种形式都提供了默认实参设置文件模式
文件模式是文件属性,而不是流属性
eg:
ifstream inFile("in.txt",ifstream::in);
ofstream outFile;
outFile.open("out.txt",ofstream::app);
文件模式及其含义
//ifstream、fstream对象关系的文件能用in打开
in 读//defalut
//ofstream、fstream对象关系的文件能用下面三者打开
out 写,隐式清空文件流(丢弃该文件以前存储的所有数据,重新写入)//default相当于out | trunc
app 每次写到文件尾(可保存该文件以前存储的所有数据,在文件尾写入)相当于out | app
trunc 写,显式清空已存在文件流
//所有文件都可用下面两者打开
ate 打开后立即定位到文件尾
binary 以二进制模式进行IO操作,不解释流中字符
eg:
fstream inOut("inOut.txt",fstream::in | fstream::out);//同时in、out不清空已存在数据
fstream inOut("inOut.txt",fstream::in | fstream::out | fstream::trunc);//指定trunc时,无论是否指定in都清空已存在数据
eg://打开并检查输入文件
ifstream& openFile(ifstream &in,const string &fileName)
{
in.close();
in.clear();
in.open(file.c_str());
return in;//无论成功与否都返回
}
字符串流
字符串流对象的使用
eg:
string line,word;
while(getline(cin,line))//read a line from the input into string:line
{
//per-line process
istringstream stream(line);//bind to stream to the line we read
while(stream >> word)//read a string:word from string:line
//per-word process
}
stringstream提供的转换和格式化
eg:
int iVal1 = 512,iVal2 = 1024;
ostringstream formatMsg;//写到
formatMsg << "Val1: " << iVal1 << "\n" << "Val2: " << iVal2 << "\n";
istringstream inputIString(formatMsg.str());//读入
string dump;
inputIString >> dump >> iVal1 >> dump >> iVal2;
cout << iVal1 << " " << iVal2 << endl;