在 C++ 的標准模板庫中提供了一組模板類來支持面向對象的數據的輸入輸出功能,如基本的輸入輸出流 istream類/ostream類,文件輸入輸出流 ifstream類/ofstream類/fstream類,字符串輸入輸出流 stringstream類/istringstream類/ostringstream類等。C++ I/O 還可以對對象進行輸入輸出操作,這些都是 C 所不具備的。這些流都位於名詞空間 std 內,一般都是以 stream為後綴。它們在數據流的處理上具有靈活、完善和強大的功能。
本章將介紹標准輸入輸出流、文件輸入輸出流和字符串輸入輸出流的相關使用。 各流類之間的繼承關系無需多說,上圖就什麼都清楚了。
#include <iostream> using namespace std; int main() { int i; float f; char s[20]; cin>>i; cin>>f; cin>>s; cout<<"i="<<i<<endl; cout<<"f="<<f<<endl; cout<<"s="<<s<<endl; return 0; }其中,插入符"<<"和提取符">>"可連續使用。對於 cin 而言,數據默認以空格分隔,上面程序中就可以使用 cin>>i>>f>>s 來賦值,可以使用 cout<<"i="<<i<<endl<<"f="<<f<<endl<<"s="<<s<<endl 來輸出。
由於 cin 默認以空格分隔,那麼如何一次性讀取一行字符串如"How are you ?"呢? get 系列函數很好地解決了這個問題。常用的 get 系列函數有三種,如下所示:
(1)get();
讀取輸入流第一個字符的ASCII值。
(2)istream& get(unsigned char * pszBuf,int nBufLen,char delim='\n');
pszBuf:指向字符串緩沖區的指針,用於保存讀取的結果。
nBufLen:指定緩沖區大小。
delim:指定分隔符,可不填,此時默認會'\n'。
(3)istream& getline(unsigned char * pszBuf,int nBufLen,char delim='\n');
參數解釋同(2),區別在於(2)遇到分隔符即停止執行,不讀取分隔符,而(3)將會讀取該分隔符,但是它不會將其存入結果緩存中。
仔細觀察下面兩段代碼的區別,比較結果,體會(2)、(3)的區別。
#include <iostream> using namespace std; int main () { char s1[100],s2[100]; cout<<"輸入:?How are you? (Tab鍵) Fine,thank you!"<<endl; int a=cin.get(); cin.get(s1,sizeof(s1),'\t'); cin.getline(s2,sizeof(s2),'\n'); cout<<"a:"<<a<<endl<<"s1:"<<s1<<endl<<"s2:"<<s2<<endl; return 0; }
//注意!只有 get() 和 getline()位置發生變化。 #include <iostream> using namespace std; int main () { char s1[100],s2[100]; cout<<"輸入:?How are you? (Tab鍵) Fine,thank you!"<<endl; int a=cin.get(); cin.getline(s1,sizeof(s1),'\t'); cin.get(s2,sizeof(s2),'\n'); cout<<"a:"<<a<<endl<<"s1:"<<s1<<endl<<"s2:"<<s2<<endl; return 0; }第一段代碼執行結果為:
#include <iostream> using namespace std; int main () { int a; cin>>a; cout<<"輸入狀態信息碼:"<<cin.rdstate()<<endl; if(cin.eof()) { cout<<"已到達流尾!"<<endl; } else { if(cin.good()) { cout<<"輸入正確!"<<endl; } if(cin.fail()) { cout<<"輸入數據類型錯誤!"<<endl; } if(cin.bad()) { cout<<"致命錯誤!"<<endl; } } return 0; }輸入:1
#include <iostream> using namespace std; int main () { int d[5]; int n=0; while(n<5) { cin>>d[n]; if(cin.fail()) { cout<<"數據類型出錯!將該數據拋棄並繼續讀取!"<<endl; cin.clear(); //清空狀態標志位 cin.get(); //將這個錯誤數據從流中讀出以拋棄 } else { cout<<"已正確讀取前"<<n+1<<"個數字: "; for(int i=0;i<=n;i++) cout<<d[i]; cout<<endl; n++; } } return 0; }輸入:
1.讀寫文本文件
文本文件是最常見的操作對象,關鍵是要解決如何按行讀、如何按行寫的問題。#include <iostream> #include <fstream> using namespace std; int main () { char s[100]; ofstream fout("test.txt"); fout<<"Hello World!"<<endl<<"How are you?"<<endl<<"Fine,thank you!"; fout.close(); ifstream fin("test.txt"); if(!fin) { cout<<"文件不存在!"; return 0; } else { while(!fin.eof()) { fin.getline(s,sizeof(s)); cout<<s<<endl; } } return 0; }
2.讀寫二進制文件
二進制文件讀寫也經常會用到,使用下面的函數來進行二進制文件讀寫。#include <iostream> #include <fstream> using namespace std; struct STUDENT { char name[20]; int ID; }; int main () { STUDENT t1={"張三",15}; STUDENT t2; ofstream fout("test.txt"); fout.write((const char*)&t1,sizeof(t1)); fout.close(); ifstream fin("test.txt"); if(!fin) { cout<<"文件打開失敗!"; return 0; } else { fin.read((char*)&t2,sizeof(t2)); cout<<t2.name<<endl<<t2.ID; fin.close(); } return 0; }
3.輸入輸出流緩沖
C++ 標准庫封裝了一個緩沖區類 steambuf,以供輸入輸出流對象使用。每個標准 C++ 輸入輸出流對象都包含一個紙箱 streambuf 的指針,用戶可以通過調用 rdbuf() 成員函數來獲得該指針,從而直接訪問底層 streambuf 對象;可以直接對底層緩沖進行數據讀寫,從而跳過上層的格式化輸入輸出操作。但由於類似的功能均可由上層緩沖區實現,因此就不加以論述了。streambuf 最精彩的部分在於它重載了 operator<< 和 operator>>。對於 operator<< 來說,它以 streambuf 指針為參數,實現把 streambuf 對象中的所有字符輸出到輸出流中;對 operator>> 來說,可把輸入流對象中的所有字符輸出到 streambuf 對象中。#include <iostream> #include <fstream> using namespace std; int main () { ifstream fin("test.txt"); if(fin) { cout<<fin.rdbuf(); } fin.close(); return 0; }同樣是將文件內容輸出,這個方法是很簡潔的。當然,如果把 cout<<fin.rdbuf() 左側的標准輸出流改成文件輸出流,則可實現文件的賦值功能等。
4.定位輸入輸出流
流的位置標識有三個:#include <iostream> #include <fstream> using namespace std; int main () { fstream fout("test.txt",ios::in|ios::out|ios::trunc); fout.write("How are you?",12); fout.seekp(0,ios::beg); //將指針移到文件頭 cout<<fout.rdbuf()<<endl; fout.seekp(4); //將指針移到流的第四個位置 cout<<fout.rdbuf()<<endl; fout.seekp(0,ios::end); //將指針移到文件尾 cout<<fout.rdbuf(); fout.close(); return 0; }輸出:
#include <iostream> #include <sstream> using namespace std; int main () { int a; float b; string c; char d[20]; string text="1 3.14 hello 你好"; string temp; istringstream sin(text); //反解字符串 sin>>a; sin>>b; sin>>c; sin>>d; cout<<a<<endl<<b<<endl<<c<<endl<<d; //合並基本類型 ostringstream sout; sout<<a<<" "<<b<<" "<<c<<" "<<d<<endl; cout<<sout.str(); return 0; }
以上就是C++ STL 基礎及應用(4) 輸出輸出流的全文介紹,希望對您學習和使用程序編程有所幫助.