以下將由問題開頭,介紹各個小重點,如果問題能正確答出來,就可以跳過該小節囉0.<
1. 寫入單位
string a = "hello" ;
cin >> a;
輸入為:
a new world
問 變數a 的內容?
- hello
- world
- a
- a new world
答案為3
原因在於空格、tab、換行都是cin的讀取變數終止條件
若讀取到這些,cin就會把剛剛讀到的東西放進變數中,以此例而言,碰到a前面的空格就結束一次操作,所以a這個變數的值被改寫成a
char a = '1' ;
char b = '2' ;
char c = '3' ;
char d = '4' ;
char e = '5' ;
cin >> a >> b >> c >> d >> e ;
cout << a << b << c << d <<e ;
輸入為:
a\tcat\n
\n
問 執行結果為? (note \t為tab,\n為換行)
- a cat
- acat\n
- a cat
- acat5
- 12345
答案為4,由此可知只要使用cin,讀取單位就連char也是會遇到空格就不反應
2. Buffer與cin.ignore()
int Number = 0;
string name[2];
while(Number<2){
cout<<"what is your name?"<<endl;
cin>>name[Number];
Number+=1;
}
輸入:
Anya Hsiao
Willy Fang
Harry Chin
//再繼續執行
string Test;
cin>>Test;
請問此時Test變數會得到甚麼結果?
- 沒有結果,等待使用者輸入
- Harry Chin
- Willy
- Fang
答案為3
除了遇到空格就將值輸入變數以外,cin/cout等IO輸入還有Buffer的存在
會先將輸出/輸入記到一塊暫存記憶體裡,方便後續cin/cout取用,所以前兩次輸入會把Anya與Hsiao吃進去,最後一個變數則會吃到Willy
如果後續還有cin,則會依序吃入Fang,Harry,Chin
cin.ignore(Max,delim)
這是一個清空buffer的函式,如果在string Test;前呼叫此函數
則會讓buffer清空,那答案就會變成1) 沒有結果,等待使用者輸入
Max參數,填入最多無視多少字元的buffer殘留內容,為一整數
delim參數,填入無視到哪一個字符停止,通常為換行
cin.ignore(256,'\n’)常常與cin.clear()一起用在發生錯誤輸入的時候
- 注意: 在unix資料重導時可能ignore會失效,要用另外的方法把cin關掉
3. Error Flag 與 cin.clear()
int a = 1024;
int b = 2048;
char c = '-';
//scanf version ===========
scanf("%d",&a);
scanf("%d",&b);
scanf("%c",&c);
// =========================
//cin version ===========
cin >> a >> b >> c
// =========================
//輸入
314 e 271
問 scanf 版本 與 cin版本 各變數內容為何(以(a,b,c)表示)?
- scanf:(314,271,e)
cin:(314,271,e) - scanf:(314,2048,-)
cin:(314,2048,-) - scanf:(314,2048,e)
cin:(314,2048,e) - scanf:(314,2048,e)
cin:(314,0,-)
答案為4
首先解釋scanf版本
a能讀到東西沒有問題
b因為當下buffer內的東西為e 271
所以會讀到e,但是e不是整數!,所以b判斷為沒有讀到東西
因此留到c讀到e,然後結束
再來解釋cin版本
a一樣沒有問題
到b時buffer內容也為e 271
但此時b讀到e發現不是整數,觸發cin的error flag ,並且將b的變數值設為0
(因此整數無端在cin收到0,就是個錯誤訊號)
觸發過error flag的cin後續將不會再傳送值給變數 ,因此即使buffer內還有e,變數c也讀不到了
會有這個差異,主要也是因為scanf是函式,而std::cin是物件,可以記錄更多狀態
此外,>>
運算符會將cin運行成功與否作為True/False回傳
這也是為甚麼可以使用if(cin»x) 或 while(cin»x)等技巧
cin.clear()
這個函式是用來讓error flag解除,使cin可以繼續工作
因此也常在error handle與 cin.ignore(max,delim)合作
如果在b讀取錯誤後加入此行,即可讓c正確的被讀入
小結
- cin是一個輸入物件,以空格,換行,tab作為讀取單位
- cin存在buffer,必要時應使用ignore(max,delim)函式清空
- cin會有error flag機制,比如將字串餵給整數變數等錯誤格式發生時會啟動,整個函數會回傳false,並將0餵給整數變數,然後後續操作都會不成功,直到cin.clear()清除這個狀態