在前面說到過每一個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指針差不多,就不贅述了。