C++复习 08 标准IO库 te> te>
声明,所有的朋友,如果要转我的帖子,务必注明"作者:黑啤来源:CSDN博客"和具体的网络地址http://blog.csdn.net/nx500/archive/2007/10/22 /1837504.aspx,并且我的所有博客内容,禁止任何形式的 商业用途,请大家尊重我的劳动.谢谢!
目 录
八.标准IO库.
001 IO对象不可复制和赋值.
1.只有支持复制的元素类型可以存储在vector或其他容器类型里.因此不存在存储流对象的vector或其他容器.
2.形参或返回类型也不能为流类型.如果需要传递或返回IO对象,则必须传递或返回指向该对象的指针或引用(非const).
002 IO标准库管理一系列条件状态成员,用来标记给定的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处于有效状态,则该函数返回true.
s.clear() 将流s中的所有状态值都重设为有效状态.
s.clear(flag) 将流s中的某个指定条件状态设置为有效.flag的类型是strm::iostate.
s.setstate(flag) 给流s添加指定条件.flag的类型是strm::iostate.
s.rdstate() 返回流s的当前条件,返回值类型为strm::iostate.
举例.
int val;
cin >> val;
如果设备输入dog,则cin在尝试将输入的字符串读为int型数据失败后,生成一个错误状态,如果输入end-of-file(^d),也会进入错误状态.
检测流是否可用最简单的方法.
if(cin)
...
while(cin >> word)
...
003 每个IO类还定义了三个iostate类型的常量值,分别表示特定的位模式.这些常量值用于指出特定类型的IO条件,可与位操作一起使用.
badbit标志着系统级的故障,如无法恢复的读写错误.如果出现了这类错误,则该流通常就不能在继续使用了.
如果出现的是可恢复的错误,如在希望获得数值类型数据时输入了字符,此时则设置failbit标志.
eofbit实在遇到文件结束符时设置的,此时同时还设置了failbit.
流的状态由bad, fail, eof和good操作揭示.clear和setstate操作用于改变条件成员的状态.
在流出现了问题并补救后,用clear重置流的状态.
004 流状态的查询和控制.
// 08004.cpp
#include <iostream>
#include <stdexcept>
#include <string>
using std::cin;
using std::cout;
using std::cerr;
using std::endl;
using std::flush;
using std::runtime_error;
using std::istream;
using std::string;
int main()...{
int ival = 0;
string dump;
try ...{
while(cin >> ival, !cin.eof())...{
if(cin.bad())...{
throw runtime_error("IO stream corrupted");
}
if(cin.fail())...{
cin.clear(); // 必须先清除cin流中的错误标记.
getline(cin,dump); // 将出错点开始的所有信息都读进来.
cout << dump << " <-" << flush;
cerr << "bad data, try again" << endl;
continue;
}
cout << ival << endl;
}
cout<<"bye!"<<endl;
}
catch(runtime_error err)...{
cerr << err.what();
}
}
这个循环不断读入cin,直到到达文件结束符或者发生不可恢复的读取错误为止.
在循环中,如果检测流已经破坏,则抛出异常,并退出循环.如果输入无效,则输出警告并清除failbit状态,再继续读入,循环判断.
005 条件状态的访问,通过rdstate可以保持当前流的状态.
istream::iostream old_state = cin.rdstate();
cin.clear();
process_input();
cin.clear(old_state);
006 多种状态的同时处理.
is.setstate(ifstream::badbit | ifstream::failbit);
007 缓冲区刷新的几种情况.
1.程序正常结束.
2.缓冲区已经满.
3.操纵符,如endl,显式的刷新缓冲区.
4.每次输出操作执行完后,用unitbuf操纵符设置流的内部状态,清空缓冲区.
5.将输入流与输出流关联一起(tie),读输入流时将刷新关联的输出缓冲区.
举例.
cout<<"hi!"<<flush; // 刷新buffer.
cout<<"hi!"<<ends; // 插入一个NULL,刷新buffer.
cout<<"hi!"<<endl; // 插入一个换行符,刷新buffer.
cout<<unitbuf<<"first"<<"sec"<<nounitbuf; // 等价于 cout<<"first"<<flush<<"sec"<<flush;
特别注意:如果程序崩溃了,并不会刷新缓冲区,所以,调试信息必须及时的顶出缓冲区,因此要多使用endl,而不是'\n'.
默认的cin和cout是关联(tie)在一起的,所以 cin>>ival; 语句会刷新cout关联的缓冲区.
tie函数可以改变关联的关系.
ostream *old_tie = cin.tie();
cin.tie(0);
cin.tie(&cerr); // 将cin与cerr关联在一起.
// ...
cin.tie(0);
cin.tie(old_tie); // 将cin与原来关联的缓冲区关联在一起.
008 fstream,由iostream派生而来,提供读写同一个文件的功能.fstream类型除了继承下来的行为外,还定了open和close两个操作.
还定义了形参为要打开的文件名的构造函数.这些操作是其他IO类型(fstrem,ifstream,ofstream以外的)所不能操作的.
需要读写文件时,必须定义自己的对象,并将他们绑定在需要的文件上.
// 假设ifile和ofile存储了希望读写文件名的string对象,可以用如下代码打开.
ifstream infile(ifile.c_str()); // 定义了输入文件流变量infile,并绑定到ifile文件上.
ofstream outfile(ofile.c_str()); // 定义了输出文件流变量outfile,并绑定到ofile文件上.
ifstream infile; // 定义了输入文件流变量infile,但没有绑定到任何文件上.
ofstream outfile; // 定义了输出文件流变量outfile,但没绑定到任何文件上.
infile.open("in"); // 使用open函数,将infile变量绑定到名为"in"的文件上.
outfile.open("out"); // 使用open函数,将outfile变量绑定到名为"out"的文件上.
可以直接判断文件是否打开成功.
if(!infile){
cerr<<"error in open input file";
}
fstream对象一旦打开,就保持与指定的文件的关联.
如果要把fstream对象与另一个不同的文件关联,则必须先关闭(close)原先的关联,在打开(open)另一个文件.
009 文件流的状态必须及时清除.
// files是一个string数组,保存文件名.
// 如果关闭文件乎忽略了clear操作,则只能打开第一个文件,此后每次打开文件后,都由于第一个文件传递给input的eofbad标识而失败.
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(s);
input.close(); // 关闭文件
input.clear(); // 注意清除input的状态
++it;
}
010 文件打开的模式. in 打开文件做读操作. out 打开文件做写操作. app 在每次写之前找到文件尾. ate 打开文件后立即将文件定位到文件尾. trunc 打开文件时清空已经存在的文件流. binary 以二进制模式进行IO操作. out,trunc和app模式只能用于指定与ofstream或fstream对象关联的文件;in模式只能用与指定ifstream或fstream对象关联的文件. 所有的文件都可以用ate和binary模式. 对于用ofstream打开的文件,要保存文件中已经存在的数据,唯一的方法是显式的指定以app的模式打开. ofstream outfile("file1"); ofstream outfile2("file1", ofstream::out | ofstream::trunc); ofstream appfile("file2", fostream::app); 对于一个文件同时进行输入输出操作. fstream inoutfile("copyOut", fstream::in | fstream::out); 模式是打开文件的属性,而不是流的属性,每次关闭流,对应的打开属性也就消失了. ofstream outfile; outfile.open("sratchpad", ofstream::out); outfile.close(); outfile.open("precious", ofstream::in); outfile.close(); 打开文件模式的有效组合. out 打开文件做写操作,删除文件中已有的数据. out | app 打开文件做添加操作,在结尾添加. out | trunc 与out相同. in 打开文件做读操作. in | out 打开文件做读写操作,并定位于文件开始处. in | out | trunc 打开文件做读写操作,删除文件中已有的数据. 上诉所有打开模式组合还可以添加ate模式,对这些模式添加ate只会改变文件打开时的初始定位,定位于文件结尾处. 一个打开并检查输入文件的程序. ifstream& open_file(ifstream &in, const string &file){ in.close(); // 由于不清楚文件流in之前的状态,所以先关闭,并清楚原始状态.. in.clear(); in.open(file.c_str()); return in; } 011 字符串流的特定操作,定义在sstream头文件中. stringstream strm; 创建自由的stringstream对象. stringstream strm(s); 创建存储s的副本的stringstream对象.s是string对象. strm.str(); 返回strm中string类型的对象. strm.str(s); 将string类型的s复制给strm,返回void. stringstream对象的使用. string line,word; while(getline(cin,line)){ // 使用getline获取整行内容. istringstream stream(line); // 将line绑定到一个istringstream对象上. while(stream>>word){ // 将line中的每个字输入到word中. // ... } } stringstream可以在各种数据类型之间实现格式化的操作.
声明,所有的朋友,如果要转我的帖子,务必注明"作者:黑啤来源:CSDN博客"和具体的网络地址http://blog.csdn.net/nx500/archive/2007/10/22 /1837504.aspx,并且我的所有博客内容,禁止任何形式的 商业用途,请大家尊重我的劳动.谢谢!
目 录
八.标准IO库.
001 IO对象不可复制和赋值.
1.只有支持复制的元素类型可以存储在vector或其他容器类型里.因此不存在存储流对象的vector或其他容器.
2.形参或返回类型也不能为流类型.如果需要传递或返回IO对象,则必须传递或返回指向该对象的指针或引用(非const).
002 IO标准库管理一系列条件状态成员,用来标记给定的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处于有效状态,则该函数返回true.
s.clear() 将流s中的所有状态值都重设为有效状态.
s.clear(flag) 将流s中的某个指定条件状态设置为有效.flag的类型是strm::iostate.
s.setstate(flag) 给流s添加指定条件.flag的类型是strm::iostate.
s.rdstate() 返回流s的当前条件,返回值类型为strm::iostate.
举例.
int val;
cin >> val;
如果设备输入dog,则cin在尝试将输入的字符串读为int型数据失败后,生成一个错误状态,如果输入end-of-file(^d),也会进入错误状态.
检测流是否可用最简单的方法.
if(cin)
...
while(cin >> word)
...
003 每个IO类还定义了三个iostate类型的常量值,分别表示特定的位模式.这些常量值用于指出特定类型的IO条件,可与位操作一起使用.
badbit标志着系统级的故障,如无法恢复的读写错误.如果出现了这类错误,则该流通常就不能在继续使用了.
如果出现的是可恢复的错误,如在希望获得数值类型数据时输入了字符,此时则设置failbit标志.
eofbit实在遇到文件结束符时设置的,此时同时还设置了failbit.
流的状态由bad, fail, eof和good操作揭示.clear和setstate操作用于改变条件成员的状态.
在流出现了问题并补救后,用clear重置流的状态.
004 流状态的查询和控制.
// 08004.cpp
#include <iostream>
#include <stdexcept>
#include <string>
using std::cin;
using std::cout;
using std::cerr;
using std::endl;
using std::flush;
using std::runtime_error;
using std::istream;
using std::string;
int main()...{
int ival = 0;
string dump;
try ...{
while(cin >> ival, !cin.eof())...{
if(cin.bad())...{
throw runtime_error("IO stream corrupted");
}
if(cin.fail())...{
cin.clear(); // 必须先清除cin流中的错误标记.
getline(cin,dump); // 将出错点开始的所有信息都读进来.
cout << dump << " <-" << flush;
cerr << "bad data, try again" << endl;
continue;
}
cout << ival << endl;
}
cout<<"bye!"<<endl;
}
catch(runtime_error err)...{
cerr << err.what();
}
}
这个循环不断读入cin,直到到达文件结束符或者发生不可恢复的读取错误为止.
在循环中,如果检测流已经破坏,则抛出异常,并退出循环.如果输入无效,则输出警告并清除failbit状态,再继续读入,循环判断.
005 条件状态的访问,通过rdstate可以保持当前流的状态.
istream::iostream old_state = cin.rdstate();
cin.clear();
process_input();
cin.clear(old_state);
006 多种状态的同时处理.
is.setstate(ifstream::badbit | ifstream::failbit);
007 缓冲区刷新的几种情况.
1.程序正常结束.
2.缓冲区已经满.
3.操纵符,如endl,显式的刷新缓冲区.
4.每次输出操作执行完后,用unitbuf操纵符设置流的内部状态,清空缓冲区.
5.将输入流与输出流关联一起(tie),读输入流时将刷新关联的输出缓冲区.
举例.
cout<<"hi!"<<flush; // 刷新buffer.
cout<<"hi!"<<ends; // 插入一个NULL,刷新buffer.
cout<<"hi!"<<endl; // 插入一个换行符,刷新buffer.
cout<<unitbuf<<"first"<<"sec"<<nounitbuf; // 等价于 cout<<"first"<<flush<<"sec"<<flush;
特别注意:如果程序崩溃了,并不会刷新缓冲区,所以,调试信息必须及时的顶出缓冲区,因此要多使用endl,而不是'\n'.
默认的cin和cout是关联(tie)在一起的,所以 cin>>ival; 语句会刷新cout关联的缓冲区.
tie函数可以改变关联的关系.
ostream *old_tie = cin.tie();
cin.tie(0);
cin.tie(&cerr); // 将cin与cerr关联在一起.
// ...
cin.tie(0);
cin.tie(old_tie); // 将cin与原来关联的缓冲区关联在一起.
008 fstream,由iostream派生而来,提供读写同一个文件的功能.fstream类型除了继承下来的行为外,还定了open和close两个操作.
还定义了形参为要打开的文件名的构造函数.这些操作是其他IO类型(fstrem,ifstream,ofstream以外的)所不能操作的.
需要读写文件时,必须定义自己的对象,并将他们绑定在需要的文件上.
// 假设ifile和ofile存储了希望读写文件名的string对象,可以用如下代码打开.
ifstream infile(ifile.c_str()); // 定义了输入文件流变量infile,并绑定到ifile文件上.
ofstream outfile(ofile.c_str()); // 定义了输出文件流变量outfile,并绑定到ofile文件上.
ifstream infile; // 定义了输入文件流变量infile,但没有绑定到任何文件上.
ofstream outfile; // 定义了输出文件流变量outfile,但没绑定到任何文件上.
infile.open("in"); // 使用open函数,将infile变量绑定到名为"in"的文件上.
outfile.open("out"); // 使用open函数,将outfile变量绑定到名为"out"的文件上.
可以直接判断文件是否打开成功.
if(!infile){
cerr<<"error in open input file";
}
fstream对象一旦打开,就保持与指定的文件的关联.
如果要把fstream对象与另一个不同的文件关联,则必须先关闭(close)原先的关联,在打开(open)另一个文件.
009 文件流的状态必须及时清除.
// files是一个string数组,保存文件名.
// 如果关闭文件乎忽略了clear操作,则只能打开第一个文件,此后每次打开文件后,都由于第一个文件传递给input的eofbad标识而失败.
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(s);
input.close(); // 关闭文件
input.clear(); // 注意清除input的状态
++it;
}
010 文件打开的模式. in 打开文件做读操作. out 打开文件做写操作. app 在每次写之前找到文件尾. ate 打开文件后立即将文件定位到文件尾. trunc 打开文件时清空已经存在的文件流. binary 以二进制模式进行IO操作. out,trunc和app模式只能用于指定与ofstream或fstream对象关联的文件;in模式只能用与指定ifstream或fstream对象关联的文件. 所有的文件都可以用ate和binary模式. 对于用ofstream打开的文件,要保存文件中已经存在的数据,唯一的方法是显式的指定以app的模式打开. ofstream outfile("file1"); ofstream outfile2("file1", ofstream::out | ofstream::trunc); ofstream appfile("file2", fostream::app); 对于一个文件同时进行输入输出操作. fstream inoutfile("copyOut", fstream::in | fstream::out); 模式是打开文件的属性,而不是流的属性,每次关闭流,对应的打开属性也就消失了. ofstream outfile; outfile.open("sratchpad", ofstream::out); outfile.close(); outfile.open("precious", ofstream::in); outfile.close(); 打开文件模式的有效组合. out 打开文件做写操作,删除文件中已有的数据. out | app 打开文件做添加操作,在结尾添加. out | trunc 与out相同. in 打开文件做读操作. in | out 打开文件做读写操作,并定位于文件开始处. in | out | trunc 打开文件做读写操作,删除文件中已有的数据. 上诉所有打开模式组合还可以添加ate模式,对这些模式添加ate只会改变文件打开时的初始定位,定位于文件结尾处. 一个打开并检查输入文件的程序. ifstream& open_file(ifstream &in, const string &file){ in.close(); // 由于不清楚文件流in之前的状态,所以先关闭,并清楚原始状态.. in.clear(); in.open(file.c_str()); return in; } 011 字符串流的特定操作,定义在sstream头文件中. stringstream strm; 创建自由的stringstream对象. stringstream strm(s); 创建存储s的副本的stringstream对象.s是string对象. strm.str(); 返回strm中string类型的对象. strm.str(s); 将string类型的s复制给strm,返回void. stringstream对象的使用. string line,word; while(getline(cin,line)){ // 使用getline获取整行内容. istringstream stream(line); // 将line绑定到一个istringstream对象上. while(stream>>word){ // 将line中的每个字输入到word中. // ... } } stringstream可以在各种数据类型之间实现格式化的操作.