我這篇博文是根據別人的博文整理而成的,因此出現和別人同樣的地方是我摘抄的,我會註明。html
在過去,咱們使用的是原始的<stdio.h>中的接口,可是今天我想講的是一個新的庫<sstream>,這個庫擁有擁有類型安全和不會溢出這樣搶眼的特性,頗有理由讓咱們使用它。下面我將詳述。ios
這份筆記我分紅了三章,分別講下面的三個部分。c++
c++的輸入輸出分爲三種:程序員
1.基於控制檯的I/O安全
2.基於文件的I/O函數
3.基於字符串的I/Ospa
開始前先偏點題,首先講講網上搜索經常能夠看到的一個問題:設計
<iostream>和<iostream.h>的區別? #include <iostream.h>非標準輸入輸出流 #include <iostream>標準輸入輸出流
C++中爲了不名字定義衝突,特別引入了「名字空間的定義」,即namespace。code
當代碼中用<iostream.h>時,輸出可直接引用cout<<x;//<iostream.h>繼承C語言的標準庫
文件,未引入名字空間定義,因此可直接使用。htm
當代碼中引入<iostream>時,輸出須要引用std::cout<<x;若是仍是按原來的方法就會有錯。
使用<iostream>時,引入std::有如下方法:
1. using namespace std; cout<<x; 2. using std::cout; cout<<x; 3. 最基本的std::cout<<x;
這回你該知道爲何一般用#include <iostream>時,要用using namespace std;了吧。若是你不用這個,就要在使用cout時,用後兩種方法了。其餘頭文件也是一樣的道理。(有「.h」的就是非標準的,C的標準庫函數,無「.h」的,就要用到命令空間,是C++的。還有一部分不徹底是有「.h」和沒「.h」的差異。例如:math.h和cmath)
咱們從一開始就一直在利用C++的輸入輸出在作着各類練習,輸入輸出是由iostream庫提供的,因此討論此標準庫是有必要的,它與C語言的 stdio庫不一樣,它從一開始就是用多重繼承與虛擬繼承實現的面向對象的層次結構,做爲一個c++的標準庫組件提供給程序員使用。
iostream爲內置類型對象提供了輸入輸出支持,同時也支持文件的輸入輸出,類的設計者能夠經過對iostream庫的擴展,來支持自定義類型的輸入輸出操做。
爲何說要擴展才能提供支持呢?咱們來一個示例。
#include <stdio.h> #include <iostream> usingnamespace std; class Test { public: Test(int a=0,int b=0) { Test::a=a; Test::b=b; } int a; int b; }; int main() { Test t(100,50); printf("%???",t);//不明確的輸出格式 scanf("%???",t);//不明確的輸入格式 cout<<t<<endl;//一樣不夠明確 cin>>t;//一樣不夠明確 system("pause"); }
因爲自定義類的特殊性,在上面的代碼中,不管你使用c風格的輸入輸出,或者是c++的輸入輸出都不是不明確的一個表示,因爲c語言沒有運 算符重載機制,致使stdio庫的不可擴充性,讓咱們沒法讓printf()和scanf()支持對自定義類對象的擴充識別,而c++是能夠經過運算符重 載機制擴充 iostream庫的,使系統能可以識別自定義類型,從而讓輸入輸出明確的知道他們該幹什麼,格式是什麼。
在上例中咱們之因此用printf與cout進行對比目的是爲了告訴你們,C與C++處理輸入輸出的根本不一樣,咱們從c的輸入輸出能夠很明顯看出是函數調用方式,而c++的則是對象模式,cout和cin是ostream類和istream類的對象。
C++中的iostream庫主要包含下圖所示的幾個頭文件:
IOSstream 庫 | |
---|---|
fstream | iomainip |
ios | iosfwd |
iostream | istream |
ostream | sstream |
streambuf | strstream |
咱們所熟悉的輸入輸出操做分別是由istream(輸入流)和ostream(輸出流)這兩個類提供的,爲了容許雙向的輸入/輸出,由istream和ostream派生出了iostream類。
iostream庫定義瞭如下三個標準流對象:
cin,表示標準輸入(standard input)的istream類對象。cin使咱們能夠從設備讀入數據。 cout,表示標準輸出(standard output)的ostream類對象。cout使咱們能夠向設備輸出或者寫數據。 cerr,表示標準錯誤(standard error)的osttream類對象。cerr是導出程序錯誤消息的地方,它只能容許向屏幕設備寫數據。
輸出主要由重載的左移操做符(<<)來完成,輸入主要由重載的右移操做符(>>)完成:
>>a表示將數據放入a對象中。 <<a表示將a對象中存儲的數據拿出。
這些標準的流對象都有默認的所對應的設備,見下表:
C++對象名 | 設備名稱 | C中標準設備名 | 默認含義 |
---|---|---|---|
cin | 鍵盤 | stdin | 標準輸入 |
cout | 顯示器屏幕 | stdout | 標準輸出 |
cerr | 顯示器屏幕 | stderr | 標準錯誤輸出 |
上表中的意思代表cin對象的默認輸入設備是鍵盤,cout對象的默認輸出設備是顯示器屏幕。
那麼原理上C++有是如何利用cin/cout對象與左移和右移運算符重載來實現輸入輸出的呢?
下面咱們以輸出爲例,說明其實現原理:
cout是ostream類的對象,由於它所指向的是標準設備(顯示器屏幕),因此它在iostream頭文件中做爲全局對象進行定義。
ostream cout(stdout);//其默認指向的C中的標準設備名,做爲其構造函數的參數使用。
在iostream.h頭文件中,ostream類對應每一個基本數據類型都有其友元函數對左移操做符進行了友元函數的重載。
ostream& operator<<(ostream &temp,int source);
ostream& operator<<(ostream &temp,char *ps);
... 等等
一句輸出語句:cout<<"http://www.cppblog.com/andxie99";,事實上調用的就是 ostream& operator<<(ostream &temp,char *ps);這個運算符重載函數,因爲返回的是流對象的引用,引用能夠做爲左值使用,因此當程序中有相似 cout<<"http://www.cppblog.com/andxie99"<<"白紙人生";這樣的語句出現的時候,就 可以構成連續輸出。
因爲iostream庫不光支持對象的輸入輸出,同時也支持文件流的輸入輸出,因此在詳細講解左移與右移運算符重載以前,咱們有必要先對文件的輸入輸出以及輸入輸出的控制符有所瞭解。