C++輸入流和輸出流 超級詳細
1、簡單介紹
C++ 又可以稱為“帶類的 C”,即可以理解為 C++ 是 C 語言的基礎上增加瞭面向對象(類和對象)。在此基礎上,學過 C 語言的讀者應該知道,它有一整套完成數據讀寫(I/O)的解決方案:
使用 scanf()
、gets()
等函數從鍵盤讀取數據,使用 printf()
、puts()
等函數向屏幕上輸出數據;
使用 fscanf()
、fgets()
等函數讀取文件中的數據,使用 fprintf()
、fputs()
等函數向文件中寫入數據。
要知道,C 語言的這套 I/O 解決方案也適用於 C++ 程序,但 C++ 並沒有“偷懶”,它自己獨立開發瞭一套全新的 I/O 解決方案,其中就包含大傢一直使用的 cin 和 cout
。前面章節中,我們一直在用 cin
接收從鍵盤輸入的數據,用 cout
向屏幕上輸出數據(這 2 個過程又統稱為“標準 I/O”)。除此之外,C++ 也對從文件中讀取數據和向文件中寫入數據做瞭支持(統稱為“文件 I/O”)。
本質上來說,C++ 的這套 I/O 解決方案就是一個包含很多類的類庫(作為 C++ 標準庫的組成部分),這些類常被稱為“流類”。
C++ 的開發者認為數據輸入和輸出的過程也是數據傳輸的過程,數據像水一樣從一個地方流動到另一個地方,所以 C++ 中將此過程稱為“流”,實現此過程的類稱為“流類”。
下圖展示瞭 C++ 中用於實現數據輸入和輸出的這些流類以及它們之間的關系:
C++類庫中的流類:
其中,圖中的箭頭代表各個類之間的派生關系。比如,ios 是所有流類的基類,它派生出
istream
和ostream
。特別需要指出的是,為瞭避免多繼承的二義性,從 ios 派生出istream
和ostream
時,均使用瞭 virtual 關鍵字(虛繼承)。
上圖 中這些流類各自的功能分別為:
istream
:常用於接收從鍵盤輸入的數據;ostream
:常用於將數據輸出到屏幕上;ifstream
:用於讀取文件中的數據;ofstream
:用於向文件中寫入數據;iostream
:繼承自istream
和ostream
類,因為該類的功能兼兩者於一身,既能用於輸入,也能用於輸出;fstream
:兼ifstream
和ofstream
類功能於一身,既能讀取文件中的數據,又能向文件中寫入數據。
本章僅講解實現標準 I/O 操作的 istream
、ostream
和 iostream
類,有關實現文件 I/O 操作的流類放到後續章節講解。
2、C++輸入流和輸出流
在前面章節的學習中,隻要涉及輸入或者輸出數據,我們立馬想到的就是 cin
和 cout
。其實,cin
就是 istream
類的對象,cout
是 ostream
類的對象,它們都聲明在 <iostream> 頭文件中,這也解釋瞭“為什麼在 C++ 程序中引入 <iostream> 就可以使用 cin 和 cout”(當然使用 cin 和 cout
,還需要聲明 std 命名空間)。
除此之外,<iostream> 頭文件中還聲明有 2 個 ostream
類對象,分別為 cerr
和 clog
。它們的用法和 cout 完全一樣,但 cerr 常用來輸出警告和錯誤信息給程序的使用者,clog
常用來輸出程序執行過程中的日志信息(此部分信息隻有程序開發者看得到,不需要對普通用戶公開)。
cout、cerr 和 clog 之間的區別如下:
cout
除瞭可以將數據輸出到屏幕上,通過重定向(後續會講),還可以實現將數據輸出到指定文件中;而cerr
和clog
都不支持重定向,它們隻能將數據輸出到屏幕上;cout
和clog
都設有緩沖區,即它們在輸出數據時,會先將要數據放到緩沖區,等緩沖區滿或者手動換行(使用換行符 ‘\n’ 或者 endl)時,才會將數據全部顯示到屏幕上;而 cerr 則不設緩沖區,它會直接將數據輸出到屏幕上。
除瞭以上 2 點特性上的不同之外,cerr
、clog
和 cout
沒有任何不同。之所以我們常用 cout,是因為 cerr 和 clog 有各自不同的適用場景。以 cerr 為例,一旦程序某處使用 cerr 輸出數據,我們自然而然地會認為此處輸出的是警告或者錯誤信息。
值得一提的是,類似
cin
、cout
、cerr 和 clog 這樣,它們都是 C++ 標準庫的開發者創建好的,可以直接拿來使用,這種在 C++ 中提前創建好的對象稱為內置對象。實際上,<iostream> 頭文件中還聲明有處理寬字符的 4 個內置對象,分別為 wcin、wcout、wcerr 以及 wclog,由於不是本節重點,這裡不再對它們做詳細講解。
如下程序演示瞭 cin
、cout
、cerr
和 clog
的基本用法:
#include <iostream> #include <string> int main() { std::string url; std::cin >> url; std::cout << "cout:" << url << std::endl; std::cerr << "cerr:" << url << std::endl; std::clog << "clog:" << url << std::endl; return 0; }
程序執行結果為:
http://c.biancheng.net
cout:http://c.biancheng.net
cerr:http://c.biancheng.net
clog:http://c.biancheng.net
註意:此程序中並沒有考慮 cerr
和 clog
各自特有的含義,這裡僅是為瞭演示 cerr
和 clog
的基礎用法,不建議讀者這樣使用。另外,如果程序中 std 命名空間提前聲明,則所有的 std::
可以省略。
它們的用法遠不止此,istream
和 ostream
類提供瞭很多實用的函數,cin
、cout
、cerr
和 clog
作為類對象,當然也能調用。
表 1 羅列瞭 cin 對象常用的一些成員方法以及它們的功能:
表 1 C++ cin 輸入流對象常用成員方法
成員方法名 | 功能 |
---|---|
getline(str,n,ch) | 從輸入流中接收 n-1 個字符給 str 變量,當遇到指定 ch 字符時會停止讀取,默認情況下 ch 為 ‘\0’。 |
get() | 從輸入流中讀取一個字符,同時該字符會從輸入流中消失。 |
gcount() | 返回上次從輸入流提取出的字符個數,該函數常和 get()、getline()、ignore()、peek()、read()、readsome()、putback() 和 unget() 聯用。 |
peek() | 返回輸入流中的第一個字符,但並不是提取該字符。 |
putback(c) | 將字符 c 置入輸入流(緩沖區)。 |
ignore(n,ch) | 從輸入流中逐個提取字符,但提取出的字符被忽略,不被使用,直至提取出 n 個字符,或者當前讀取的字符為 ch。 |
operator>> | 重載 >> 運算符,用於讀取指定類型的數據,並返回輸入流對象本身。 |
表 2 羅列瞭 cout、cerr 和 clog 對象常用的一些成員方法以及它們的功能:
表 2 C++ cout 輸出流對象常用成員方法
成員方法名 | 功能 |
---|---|
put() | 輸出單個字符。 |
write() | 輸出指定的字符串。 |
tellp() | 用於獲取當前輸出流指針的位置。 |
seekp() | 設置輸出流指針的位置。 |
flush() | 刷新輸出流緩沖區。 |
operator<< | 重載 << 運算符,使其用於輸出其後指定類型的數據。 |
舉個例子:
#include <iostream> using namespace std; int main() { char url[30] = {0}; //讀取一行字符串 cin.getline(url, 30); //輸出上一條語句讀取字符串的個數 cout << "讀取瞭 "<<cin.gcount()<<" 個字符" << endl; //輸出 url 數組存儲的字符串 cout.write(url, 30); return 0; }
程序執行結果為:
http://c.biancheng.net
讀取瞭 23 個字符
http://c.biancheng.net
註意:表 1 和表 2 中僅羅列瞭 istream
和 ostream
類中常用的一些成員方法,關於這些方法的具體用法,後續章節會做詳細介紹。
到此這篇關於C++輸入流和輸出流 超級詳細的文章就介紹到這瞭,更多相關C++輸入流和輸出流內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!