|
字節(jié)流可直接與內(nèi)存而不是與文件或標準輸出一起工作。我們可以用與標準輸出同樣的格式,操作內(nèi)存里的數(shù)據(jù)(字節(jié))。如果我們想把數(shù)據(jù)放入字節(jié)流,可以建立一個ostrstream對象;如果想從字節(jié)流中提取數(shù)據(jù),就建立一個istrstream對象。
12.3.1 輸入流
istrstream類支持一個字符數(shù)組作為源的輸入流。在構(gòu)造istrstream對象前,必須存在一個字符數(shù)組,而且這個數(shù)組中已經(jīng)填充了我們想要提取的字符。下面是兩個構(gòu)造函數(shù)的原型:
istrstream::istrstream(char* buf);
istrstream::istrstream(char* buf, int size);
第一個構(gòu)造函數(shù)取一個指向以"{content}"作為結(jié)尾符的字符數(shù)組的指針,我們可以提取字節(jié)直至遇到"{content}"為止。第二個構(gòu)造函數(shù)還需要這個數(shù)組的大小,但不需要數(shù)組包含字符串的結(jié)尾符"{content}",我們可以一直提取字節(jié)到buf[size-1],而不管是否遇到"{content}"。
程序段 程序12-17
#include "strstrea.h"
//使用strstream要包含頭文件strstrea.h
//這個文件名很奇怪,這是因為DOS文件命名規(guī)則的限制。
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;
}
程序的運行結(jié)果是:
n=3
f=0.14159
buf=hello
在程序中變量n提取到的是3,變量f提取到的是0.14159,這說明抽取不僅依賴于空白的分隔符,還依賴于提取的數(shù)據(jù)類型。同時,程序中也會出現(xiàn)前面提到的問題。例如:
istrstream arg("3.14159 hello world!");
的運行結(jié)果并不是想象中那樣,把"hello world!"被抽取到buf中,僅僅是hello被抽取。
如果該輸入流定義為:
istrstream arg("3.14159 hello",10);
強制限定字符數(shù)組元素個數(shù)為10,則程序運行結(jié)果為:
n=3
f=0.14159
buf=he
12.3.2 輸出流
ostrstream類支持一個字符數(shù)組作為數(shù)據(jù)傳輸目的地的輸出流,它可以使用我們?yōu)樗暾埖拇鎯臻g,這時字節(jié)在內(nèi)存中被格式化;也可以使用自動分配的存儲空間。
我們?yōu)閛strstream申請存儲空間的方法是通過ostrstream有參的構(gòu)造函數(shù):
ostrstream(char*, int, int=ios::out);
第一個參數(shù)是緩沖區(qū)的指針,第二個參數(shù)是緩沖區(qū)的大小,第三個參數(shù)是打開模式。如果是缺省的模式,則從緩沖區(qū)頭部開始添加新的字符;如果打開模式是ios::ate或ios::app,則從緩沖區(qū)中的字符串的結(jié)尾符處開始添加新的字符 (結(jié)尾符不后移,只是被簡單地覆蓋,下面程序中os<<ends的作用就是在buf后面加上結(jié)尾符)。
下面是一個使用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;
}
程序的運行結(jié)果是:
n=3
f=0.14159
如果使用自動分配存儲空間的方法,則使用無參的構(gòu)造函數(shù):
ostrstream os;
這時對象os在堆中分配一塊存儲空間,并自己維護。當(dāng)用戶輸入不斷增加,原存儲塊不夠用時,它可以再分配更多的存儲空間。用戶可以通過調(diào)用成員函數(shù)rdbuf()返回緩沖區(qū)指針,以訪問緩沖區(qū)的內(nèi)容。
ostrstream類支持一個字符數(shù)組作為數(shù)據(jù)傳輸目的地的輸出流,它可以使用我們?yōu)樗暾埖拇鎯臻g,這時字節(jié)在內(nèi)存中被格式化;也可以使用自動分配的存儲空間。
我們?yōu)閛strstream申請存儲空間的方法是通過ostrstream有參的構(gòu)造函數(shù):
ostrstream(char*, int, int=ios::out);
當(dāng)插入操作超過申請的存儲空間的小時,流的bad標志會置位。
如果使用自動分配存儲空間的方法,則使用無參的構(gòu)造函數(shù):
ostrstream os;
當(dāng)不知道數(shù)據(jù)需要多少空間時,這是一種很好的方法。這時對象os在堆中分配一塊存儲空間,并自己維護。當(dāng)用戶輸入不斷增加,原存儲塊不夠用時,如果有必要,它將移動存儲塊以分配更多的存儲空間。用戶可以通過調(diào)用成員函數(shù)rdbuf()返回緩沖區(qū)指針,以訪問緩沖區(qū)的內(nèi)容。但是有一個問題:當(dāng)空間不夠,流對象自己移動存儲塊以分配更多空間時,原來的緩沖區(qū)指針已經(jīng)失效,但是用戶是不知道的,因為流對象自己負責(zé)維護存儲空間。ostrstream處理這個問題的方法是"凍結(jié)"自己。用戶通過str()函數(shù)返回指向輸出流內(nèi)容的字符數(shù)組的指針,并將自己"凍結(jié)"。用戶不能再它添加字符,ostrstream對象也不再負責(zé)存儲空間的自動釋放,必須由用戶自己清理存儲器:
delete os.str();
如果想添加更多的字符,一般的做法是新建一個ostrstream,將舊的流灌入新流中,并向新流添加字符。
|
|