在前面說到過每一個iostream對象都有一個緩沖區,我們稱之為流緩沖區,那個這個所謂的流緩沖區是怎 麼存在的呢?iostreams中將該流緩沖區抽象為一個類,即streambuf類。
每個iostream的類都會包含 一個指向streambuf對象的指針,這也就意味著我們可以直接的去訪問到這個指針,並向該streambuf對象發送 消息等(但是一般情況下我們並不需要這樣做)。
既然說我們可以得到這個指針,那isotreams類當然 會提供訪問的接口了,這就是const成員函數rdbuf(),它會返回iostream對象所有的streambuf也就是緩沖區 的指針。那這個緩沖區的指針有什麼用呢?最常用的就是直接對其進行輸入輸出操作,看下面的例子:
1.txt內容: hello world~~!! my name is zorro. nice to meet you~
int main() {
ifstream fin("1.txt");
cout << fin.rdbuf() << endl;
system("pause");
return 0;
}
上面的程序輸出為:

可見對這個streambuf對象的指 針進行輸出操作,直接輸出了緩沖區的所有內容,這是個很方便的功能。但是要注意的是,對rdbuf()返回的 指針進行輸出,一定得到的是整個緩沖區的內容嗎?再看下面的例子:
int main() {
ifstream fin("1.txt");
string str;
fin >> str;
cout << fin.rdbuf() << endl;
system("pause");
return 0;
}
上面的程序輸出為:

可見對rdbuf()進行輸出得到的 並不一定是整個緩沖區的內容。為了對這個東西進行說明,我們必須先要了解緩沖區擁有的兩個指針,我們一 般稱之為get指針和put指針。
對於streambuf類(其實就是basic_streambuf<char>類),可以 看出它的操作是以字節(char)為單位的,所以get指針與put指針也是以字節為單位移動的。get指針指向的 是緩沖區中下一個將要提取的字節,put指針指向的是向緩沖區中輸出數據的下一個位置。可以通過成員函數 seekg來移動get指針,seekp來移動put指針。當然從上面的描述我們可以看到,get指針是對輸入的操作,put 指針是對輸出的操作,所以在類似ifstream這樣的輸入功能類中,是沒有seekp函數只有seekg函數的,同樣在 ofstream也只有seekp函數沒有seekg的。看下面的例子:
int main() {
ifstream fin("1.txt");
string str;
fin >> str;
fin.seekg(2,ios::beg);
cout << fin.rdbuf() << endl;
system("pause");
return 0;
}
這個程序的輸出為:

可見對於rdbuf()返回的指針的 輸出,並不是直接輸出緩沖區中的所有內容,而是輸出get指針後面的內容。
iostream同樣提供了成員 函數tellg和tellp,這兩個函數返回的是當前get指針和put指針的位置,返回的類型是streampos,它們同樣 很有用,可以用來臨時存儲一個位置。看下面的例子:
#define PRINTCURPOS(in) cout <<
"cur pos:" << in.tellg() << endl
#define PRINTANDEXEC(st) cout << #st << endl; st
int main() {
PRINTANDEXEC(ifstream fin("1.txt"));
PRINTANDEXEC(string str);
PRINTCURPOS(fin);
PRINTANDEXEC(fin >> str);
PRINTCURPOS(fin);
PRINTANDEXEC(fin.seekg(2,ios::beg));
PRINTCURPOS(fin);
PRINTANDEXEC(cout << fin.rdbuf() << endl);
PRINTCURPOS(fin);
system("pause");
return 0;
}
上面的程序輸出為:

以上只演示了get指針的的使用 ,關於put指針的使用跟get指針差不多,就不贅述了。