經常要使用到cin和cout,花了點時間,把常見的問題整理了一下,供記性不好時查閱。
在程序中包含iostream文件將自動創建cin對象和cou對象,即標準輸入流和標準輸出流。
關於cout :
<<操作符的默認含義是按位左移操作符,但ostream類重新定義了<<操作符,將其重載爲輸出方法。<<支持C++的所有的基本類型。對於每一種數據類型,C++都提供了operator<<()的定義。例如,如果表達式cout << 100對應於下面的方法:
Ostream & operator<<(int);
Ostream類還爲以下的指針類型定義了插入操作符函數:
Const signed char*;
Const unsigned char*;
Const char*;
Void *;
Cout 支持拼接輸出:
如: cout << "hello" <<"world"<<endl;
怎樣刷新輸出緩衝區?
由於ostream對cout對象處理的輸出進行緩衝,所以輸出不會立即發送到目的地址,而是被存儲在緩衝區中,直到緩衝區填滿。然後,程序將刷新緩衝區,把內容發送出去,並清空緩衝區,以存儲新的數據。通常,緩衝區爲512字節或其整數倍。
有兩種方式實現緩衝區的手動刷新:
Flush:刷新緩衝區
Endl:刷新緩衝區,並插入一個換行符
例如:
cout << "hello world" << flush;
Cout << "hello world" <<endl;
關於cin:
Cin對象將標準輸入表示爲字節流。輸入可以是字符串的一部分、int值、float值等,istreaml類重載了抽取操作符>>,使之能夠識別C++所有的基本數據類型,所以,抽取還涉及到類型轉換。編譯器將根據數據接收者的類型,匹配適當的的函數。
例如: cin >> value_holder
如果value_holder爲int型,則將匹配函數
istream & operator>>(int &); //注意函數原型,參數和返回值都是引用
而如果value_holder爲char類型,則將匹配函數
istream & operator >>(char &);
istream類爲下列字符指針類型重載了>>抽取操作符:
signed char*;
char *;
unsigned char *;
Cin的常見用法:
用法1:最基本,也是最常用的用法,輸入一個數字:
- #include <iostream>
- using namespace std;
- int main () {
- int a,b;
- cin>>a>>b;
- cout<<a+b<<endl;
- return 0;
- }
注意:>> 是會過濾掉不可見字符(如 空格 回車,TAB 等)
cin>>noskipws>>input[j];//不想略過空白字符,那就使用 noskipws 流控制
用法2:接受一個字符串,遇“空格”、“TAB”、“回車”都結束
- #include <iostream>
- using namespace std;
- int main () {
- char a[20];
- cin>>a;
- cout<<a<<endl;
- return 0
- }
Cin有一個比較“智能”之處,即它會讀取從非空白字符開始,到與目標類型不匹配的第一個字符之間的全部內容。
例如,對於下面的代碼:
Int value;
Cin >> -123a;
操作符將提取-,1,2,3,因爲它們都是整數的有效部分。但是a字符不是有效字符,因此輸入中最後一個可接受的字符是3,a將留在輸入流中,下一個cin語句將從這裏開始讀取。與此同時,操作符將字符序列-123轉換爲一個整數值,並將它賦給value。
怎樣實現循環輸入?
先看這樣一段代碼:
- int sum =0;
- int input;
- While(cin >> input){
- Sum += input;
- }
這段代碼實現了循環輸入,循環體中當然可以用別的數據結構比如容器來接收輸入,這不是一個死循環嗎?當然,如果一直輸入的是正確的int型數據,輸入將一直進行下去,直到地老天荒!結束這個循環的方法很簡單,輸入一個錯誤字符即可。
當cin操作未能讀取到預期的字符時,它將設置流狀態failbit.,此時,if或者else將斷定cin對象爲false。
怎樣恢復流狀態?
當>>提取到非預期字符時,會設置failbit,此時流會關閉。如果要繼續輸入,必須要重置流狀態,同時還要清空流緩存中遺留的數據。
Cin.clear();//重置流狀態
Cin.sync();//清空流緩存
這兩個函數要同時使用纔算完成重置流狀態。
以下代碼說明sync()函數的功能:
- #include <iostream>
- using namespace std;
- int main () {
- char first, second;
- cout << "Please, enter a word: ";
- first=cin.get();
- cin.sync();
- cout << "Please, enter another word: ";
- second=cin.get();
- cout << "The first word began by " << first << endl;
- cout << "The second word began by " << second << endl;
- return 0;
- }
怎樣得到整行數據?
如果想得到整行數據,cin有諸多限制。這時可以借用非格式化輸入函數。
istream & getline(char*,int,char);
istream & getline(char* ,int);
這是istream提供的整行錄入函數,但是都需要制定接收字符串的長度,streamstring提供了一個更便捷的getline版本:
istream &getline(istream&,string)
這個函數接受兩個參數:一個輸入流對象和一個string對象。getline函數從輸入流的下一行讀取,並保存讀取的內容到string中,但不包括換行符。和輸入操作符不一樣的是,getline並不忽略行開頭的換行符。只要getline遇到換行符,即便它是輸入的第一個字符,getline也將停止讀入並返回。如果第一個字符就是換行符,則string參數將被置爲空string。
getline函數將istream參數作爲返回值,和輸入操作符一樣也把它用作判斷條件。
例如:
- int main(){
- string line;
- while (getline(cin, line))
- cout << line << endl;
- return 0;
- }
由於getline函數返回時丟棄換行符,換行符將不會存儲在string對象中。
《C++ primer》
《C++ primer plus》