C++問題集合
本文最後更新於:2022年4月17日 下午
C++問題集合
在 cin>> 後呼叫 getline 會遇到 buffer 沒有清空
總結:
多次使用cin>>,cin.getline(), getline()
- 每次使用了cin>>之後,都會在緩衝區中多出來一個換行符(因為會敲下enter,代表輸入資料時,一個
\n
會被插入到輸入流之中 ),所以每次使用了cin>>之後都需要利用「cin.ignore()
」將多出來的換行符處理掉;
如果連續兩次都是cin>>,就不需要將多出來的換行符去掉了。
因為cin的時候,並不是只要讀取到換行符就執行完cin,而是必須要讀取到相對應的類型的內容從鍵盤敲入,才會真正執行完cin
- cin不允許輸入為空
- 所以cin>>在等待鍵盤敲入時,就算先敲換行符,cin>>語句也不會執行結束。
- 簡單來說,cin一定要吃到資料,並且在遇到換行符時結束(不會吃進換行符)
但是cin.getline()函數和getline()函數,它們都是以換行符作為唯一的標準
- getline()允許輸入為空,也就是說直接一個換行符就結束,
- 也可以吃進 「包含空白符的字串」,直到遇到換行符
原因:
cin >> value
; cin會在遇到換行符時停止,這個換行符會被留在鍵盤緩衝區中
而 「從鍵盤讀取數值的輸入語句,只在鍵盤緩衝區為空時,才會等待用戶輸入值」
然後我們在鍵盤上鍵入 2,然後敲一個 enter。
這個時候,我們的電腦其實得到的是底下的資訊:
緩衝區中有一個 2,還有一個斷行。
那第8行再讀時,只會把 2 讀出來(因為我們要求讀一個整數,而 endl 不是整數,所以不會被讀出來)。
所以最後,緩衝區中會遺留一個 endl 在那兒。於是下次我們呼叫 getline 時,由於 C++ 偵測到緩衝區中還有資料,所以會先把那個 endl 讀出來。這就是為什麼我們只能讀到一個字串的原因。
解決的方法有很多,最常見的有兩個:
- 在 cin 後,要是我們知道要呼叫 getline,那就「多呼叫一次 getline」,把緩衝區清空。
1 |
|
使用cin.get()
- get 函數讀取單個字符,包括任何white space字符
1
2
3char ch;
cin.get(ch);//法一
cin.get();//法二呼叫 cin.ignore() 把緩衝區清空。
1 |
|
該預設版本的ignore 會清空緩衝區,直到底下的兩個條件,其中一個滿足為止!
- 清空 1 個字元。
- 讀到 endl。
所以如果多了一些意外出現的字元,還是會無法把endl清理掉!
改良版本:
1 |
|
參考資料:
[C++]在 cin 後呼叫 getline 所遇到的問題 (justimchung.blogspot.com)
(6条消息) C++中的cin, cin.getline, getline等混合使用时不能输入直接执行下一行的问题_Leonardo Liu的博客-CSDN博客_c++ cin getline
endl
和 \n
的區別
\n只代表換行的轉義字符;
- 輸出’\n’是實際輸出了的’\10’,往輸出流裡添加了訊息
endl除了代表換行,還緊跟著清出緩衝槽
- endl是C++中使用的io流換行
- 輸出endl不會往輸出流裡添加東西,只會簡單的刷新流並換行
參考資料:
https://blog.csdn.net/u011675745/article/details/51939094
命名空間namespace
C++標準為了和C區別開,也為了正確地使用名稱空間,規定標頭檔案不使用字尾.h*當使用
- 如果你的應用程式是多個團隊共同合作,如果沒有定義名稱空間,名稱預設都是位於全域名域空間,以類別定義來說,那麼若 A 部門寫了個 Account 類別,B 部門寫了個 Account 類別,當他們要將應用程式整合時,就會發生名稱衝突的問題。
https://www.itread01.com/content/1547346090.html
由於namespace的概念,使用C++標準程式庫的任何識別符號時,可以有三種選擇:
- 直接指定識別符號
例如:
std::iostream而不是iostream。完整語句如下: std::cout << std::hex << 3.4 << std::endl;
- 使用using關鍵字
例如:
using std::cout; using std::endl; using std::cin; 以上程式可以寫成如下程式碼:
using std::cout <<using std::hex << 3.4 <<using std:: endl;
- 使用using namespace std
例如:
#include
#include
#include
using namespace std;
這樣名稱空間std內定義的所有識別符號都有效(曝光)。就好像它們被宣告為全域性變數一樣。