字节流可直接与内存而不是与文件或标准输出一起工作。我们可以用与标准输出同样的格式,操作内存里的数据(字节)。如果我们想把数据放入字节流,可以建立一个ostrstream对象;如果想从字节流中提取数据,就建立一个istrstream对象。
12.3.1 输入流
istrstream类支持一个字符数组作为源的输入流。在构造istrstream对象前,必须存在一个字符数组,而且这个数组中已经填充了我们想要提取的字符。下面是两个构造函数的原型:
istrstream::istrstream(char* buf);
istrstream::istrstream(char* buf, int size);
第一个构造函数取一个指向以"{content}"作为结尾符的字符数组的指针,我们可以提取字节直至遇到"{content}"为止。第二个构造函数还需要这个数组的大小,但不需要数组包含字符串的结尾符"{content}",我们可以一直提取字节到buf[size-1],而不管是否遇到"{content}"。
程序段 程序12-17
#include "strstrea.h"
//使用strstream要包含头文件strstrea.h
//这个文件名很奇怪,这是因为DOS文件命名规则的限制。
void main()
{
int n;
float f;
char buf[80];
istrstream arg("3.14159 hello");
arg>>n>>f>>buf;
cout<<"n="<<n<<endl;
cout<<"f="<<f<<endl;
cout<<"buf="<<buf<<endl;
}
程序的运行结果是:
n=3
f=0.14159
buf=hello
在程序中变量n提取到的是3,变量f提取到的是0.14159,这说明抽取不仅依赖于空白的分隔符,还依赖于提取的数据类型。同时,程序中也会出现前面提到的问题。例如:
istrstream arg("3.14159 hello world!");
的运行结果并不是想象中那样,把"hello world!"被抽取到buf中,仅仅是hello被抽取。
如果该输入流定义为:
istrstream arg("3.14159 hello",10);
强制限定字符数组元素个数为10,则程序运行结果为:
n=3
f=0.14159
buf=he
12.3.2 输出流
ostrstream类支持一个字符数组作为数据传输目的地的输出流,它可以使用我们为它申请的存储空间,这时字节在内存中被格式化;也可以使用自动分配的存储空间。
我们为ostrstream申请存储空间的方法是通过ostrstream有参的构造函数:
ostrstream(char*, int, int=ios::out);
第一个参数是缓冲区的指针,第二个参数是缓冲区的大小,第三个参数是打开模式。如果是缺省的模式,则从缓冲区头部开始添加新的字符;如果打开模式是ios::ate或ios::app,则从缓冲区中的字符串的结尾符处开始添加新的字符 (结尾符不后移,只是被简单地覆盖,下面程序中os<<ends的作用就是在buf后面加上结尾符)。
下面是一个使用istrstream的例子:
程序段 程序12-18
#include "strstrea.h"
void main()
{
int n;
float f;
char buf[80];
ostrstream os(buf,80);
cin>>n>>f;
os<<"n="<<n<<endl;
os<<"f="<<f<<endl;
os<<ends;
cout<<buf;
}
程序的运行结果是:
n=3
f=0.14159
如果使用自动分配存储空间的方法,则使用无参的构造函数:
ostrstream os;
这时对象os在堆中分配一块存储空间,并自己维护。当用户输入不断增加,原存储块不够用时,它可以再分配更多的存储空间。用户可以通过调用成员函数rdbuf()返回缓冲区指针,以访问缓冲区的内容。
ostrstream类支持一个字符数组作为数据传输目的地的输出流,它可以使用我们为它申请的存储空间,这时字节在内存中被格式化;也可以使用自动分配的存储空间。
我们为ostrstream申请存储空间的方法是通过ostrstream有参的构造函数:
ostrstream(char*, int, int=ios::out);
当插入操作超过申请的存储空间的小时,流的bad标志会置位。
如果使用自动分配存储空间的方法,则使用无参的构造函数:
ostrstream os;
当不知道数据需要多少空间时,这是一种很好的方法。这时对象os在堆中分配一块存储空间,并自己维护。当用户输入不断增加,原存储块不够用时,如果有必要,它将移动存储块以分配更多的存储空间。用户可以通过调用成员函数rdbuf()返回缓冲区指针,以访问缓冲区的内容。但是有一个问题:当空间不够,流对象自己移动存储块以分配更多空间时,原来的缓冲区指针已经失效,但是用户是不知道的,因为流对象自己负责维护存储空间。ostrstream处理这个问题的方法是"冻结"自己。用户通过str()函数返回指向输出流内容的字符数组的指针,并将自己"冻结"。用户不能再它添加字符,ostrstream对象也不再负责存储空间的自动释放,必须由用户自己清理存储器:
delete os.str();
如果想添加更多的字符,一般的做法是新建一个ostrstream,将旧的流灌入新流中,并向新流添加字符。
|