您的位置:首页 > 编程语言 > C语言/C++

C++ Primer_标准IO库杂记

2011-12-04 16:04 225 查看
IO类型在三个独立的头文件中定义:

iostream定义读写控制窗口

fstream定义读写已命名文件类型

而ssrteam所定义的类型则用于读写存储在内存中的string对象

IO对象不可复制或赋值

标准库类型不允许做复制或赋值操作

只有支持复制的元素类型可以存储在vector或其他容器类型里,所以标准库类型不能存储在vector或其他类型的容器中

形参或返回类型也不能也不能为流类型,如果需要传递或返回IO对象

则必须传递或返回指向该对象的指针或引用

条件状态:

流必须处于无错误状态才能用于输入或输出

所有流对象都包括一个条件状态成员

给成员由setstate和clear操作管理。这个状态成员为iostate类型,这是由各个iostream类分别定义的机器相关的整型

badbit:系统级故障,不可恢复

failbit:可恢复错误,通常是可以修正的(如:类型错误)

eofbit:遇见文件流结束符(同时还设置了failbit)

可用setstate和clear改变流状态

setstate若要同时设置多种状态可以用按位或符连接多个状态

输出缓冲区的管理

1.程序正常结束时,作为main返回工作的一部分,将清空所有输出缓冲区

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

3.用操纵符显式刷新缓冲区,如endl

4.在每次输出操作执行完毕后,用unitbuf操纵符设置流的内部状态,从而清空缓冲区

5.将输入流和输出流关联后,再度输入流时将刷新其关联的缓冲区

输出缓冲区的刷新

flush:用于刷新流,但不在输出中添加任何字符

ends:在输出缓冲区添加空字符null,然后刷新它

unitbuf(适用于需要刷新所有输出)

在每次执行完操作后刷新流

cout<<unitbuf<<"a"<<"b"<<unitbuf;

等价于

cout<<"a"<<flush<<"b"<<flush;

nounitbuf操纵符将流恢复为使用正常的,由系统管理的缓冲区刷新方式

如果程序崩溃了则不会刷新缓冲区

因此要显式的调用flush或者endl

输出时尽量使用endl而不是'\n'

交互式系统通常确保他们的输出流和输入流是绑定在一起的

这样做意味着了以保证任何输出包括给用户的提示都在试图读之前输出

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,则打破该流上已存在的捆绑。

由于历史原因,IO 标准库使用 C 风格字符串而不是 C++

strings 类型的字符串作为文件名。

文件模式

in 打开文件做读操作

out 打开文件做写操作

app 在每次写之前找到文件尾

ate 打开文件后立即将文件定位在文件尾

trunc 打开文件时清空已存在的文件流

binary 以二进制模式进行 IO 操作

默认时,与 ifstream 流对象关联的文件将以 in 模式打开,该模式允许文

件做读的操作:与 ofstream 关联的文件则以 out 模式打开,使文件可写。以

out 模式打开的文件会被清空:丢弃该文件存储的所有数据。

从效果来看,为 ofstream 对象指定 out 模式等效于同时指定

了 out 和 trunc 模式。

对于用 ofstream 打开的文件,要保存文件中存在的数据,唯一方法是显式

地指定 app 模式打开

默认情况下fstream对象以in和out模式同时打开

另外有:

in|out 不清空

out 清空

trunc 清空

#include<iostream>
#include<stdexcept>
#include<fstream>
using namespace std;

istream& IO(istream& input)
{
string str;
while(input>>str)// 未到达文件末尾
{
if(input.bad())//系统级的错误
throw runtime_error("IO stream corrupt");//抛出异常
if(input.fail())//可恢复错误
{
cerr<<"bad data , try again ";//将错误信息写出到标准错误流
input.clear();//清除出错状态
continue;
}
cout<<str<<endl;
}
input.clear();//清除出错状态
return input;
}

int main()
{
ifstream ifs;//定义文件流输出对象
ifs.open("input.txt");//打开文件
if(ifs)//如果打开成功
IO(ifs);
ifs.close();//关闭文件
system("pause");
return 0;
}


stringstream 对象的一个常见用法是,需要在多种数据类型之间实现自动

格式化时使用该类类型。例如,有一个数值型数据集合,要获取它们的 string 表

示形式,或反之。sstream 输入和输出操作可自动地把算术类型转化为相应的

string 表示形式,反过来也可以。

#include<sstream>
#include<iostream>
#include<string>
using namespace std;

int main()
{
int val1=512,val2=1024;
ostringstream format_message;
// ok: converts values to a string representation
format_message<<"val1: "<<val1
<<"val2: "<<val2<<endl;
// str member obtains the string associated with a stringstream
istringstream input_istring(format_message.str());
string dump;// place to dump the labels from the formatted message
// extracts the stored ascii values, converting back to arithmetic
input_istring>>dump>>val2>>dump>>val1;
cout<<val2<<" "<<val1<<endl;
system("pause");
return 0;
}


#include<iostream>
#include<string>
#include<vector>
#include<fstream>
#include<sstream>
using namespace std;

void WritesStr(ofstream& ofs,const char* filename)
//随机生成字符串输出到filename所存储的文件名中
{
ofs.open(filename);
if(!ofs)
{
cerr<<"Can't open file "<<filename<<" ! "<<endl;
return;
}
string str[20]={"I","am","a","coder","top","in","the","world","believe","you",
"know","it","just","know","hate","ditry","boy","girl","murder","srteam"};
int linenum,linelen;
srand((unsigned)time(NULL));
linenum=rand()%1000;
for(int i=0;i<linenum;i++)
{
linelen=rand()%10;
for(int j=0;j<linelen;j++)
ofs<<str[rand()%20]<<" ";
ofs<<endl;
}
ofs.close();
}

void ReadLine(vector<string>& line,const char* filename)
//从filename所存储的文件名中读取字符串储存到vector容器中
{
ifstream ifs;
ifs.open(filename);
if(!ifs)
return;
string str;
while(getline(ifs,str))
line.push_back(str);
ifs.close();
}

int main()
{
ofstream ofs;
WritesStr(ofs,"input.txt");

vector<string>line;
ReadLine(line,"input.txt");

vector<string>::iterator it=line.begin();//定义迭代器
istringstream in;
while(it!=line.end())//遍历
{
in.str(*it);
//将一个string类型的对象绑定到istringstream的对象中
string str;
while(in>>str)//遍历该string对象中的内容
{
if(str=="believe")//如果有单词“believe”
{
cout<<*it<<endl;//写出到标准输出
break;
}
}
in.clear();
it++;
}
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: