C++ 讀取鍵盤輸入(cin/cin.getline()/cin.get()/cin.clear())
1.cin
C++ 使用cin可以方便的讀取鍵盤輸入的字元,例如:
-
//test input
-
#include <iostream>
-
int main()
-
{
-
using
namespace
std;
-
const
int size =
20;
-
char
name[size];
-
char pl[size];
//program language
-
-
cout<<
"Enter your name:";
-
cin>>name;
-
cout<<
"Enter your favorite program language:";
-
cin>>pl;
-
cout<<
"Hello "<<name<<
", your favorite program language is "<<pl<<
endl;
-
return
0;
-
}
首先,每個輸入我們只輸入一個單詞,如下:
但如果我們在第一個輸入時填寫兩個以上單詞:
可以發現,第二個輸入還沒來得及響應,就已經都顯示出來了。
原因是:cin通過使用空白(空格、製表符和換行符)來定字串的界。這意味著cin在讀取字元陣列輸入時只讀取一個單詞,讀取該單詞後,cin將該字串放一陣列中,並自動結尾新增空字元。另外,cin也沒有很好的控制元件輸入的字元數,即輸入字元數大於陣列大小的情況沒有處理。
2.cin.getline()
基於上面的情況,使用cin.getline()讀取一行資料。
cin.getline()函式讀取整行,它使用通過回車鍵輸入的換行符來確定輸入結尾。該函式有兩個引數。第一個引數是用來儲存輸入行的陣列的名稱,第二個引數是要讀取的字元數(包括空字元),cin.getline()成員函式在讀取指定數目的字元或遇到換行符時停止讀取
如下:
-
cout<<
"Enter your name:";
-
cin.getline(name,size);
-
cout<<
"Enter your favorite program language:";
-
cin.getline(pl,size);
-
cout<<
"Hello "<<name<<
", your favorite program language is "<<pl<<
endl;
現在再來獲得多個單詞的輸入:
發現就正常了。需要注意的是,cin.getline()丟棄了換行符。
3.cin.get()
get()函式有好幾種變體,其中有一種與getline()完全相同的引數,但該函式不再讀取並丟棄換行符(不讀取意味著換行符還在輸入佇列中):
-
cout<<
"Enter your name:";
-
cin.get(name,size);
-
cout<<
"Enter your favorite program language:";
-
cin.get(pl,size);
-
cout<<
"Hello "<<name<<
", your favorite program language is "<<pl<<
endl;
嘗試輸入:
發現並不好使,原因是由於第一次呼叫後,換行符將留存輸入佇列中,因此第二次呼叫時看到的第一個字元為換行符。因此get認為已經到達行尾,而沒有發現任何可讀取的內容。get()(不帶任何引數的變體)可以讀取下一個字元(包括換行符)。因此可以:
-
cin.get(name,size).get();
-
cin.get(pl,size).get();
即可。
注意:有些C++版本沒有不帶引數的get()變體。可能有隻有char引數的變體。可用下面的代替:
char ch;cin.get(name,size).get(ch);
4.讀取空行和其他問題
當getline()或get()讀取空行時將如何?一般是下一條輸入語句將在前一條結束讀取的位置開始讀取;但當有空行時,當get()讀取空行後將設定失效位(failbit),這意味接下來的輸入將被阻斷,但可以用下面的命令來恢復輸入:cin.clear() cout<<”Enter your name:”;
-
cout<<
"Enter your name:";
-
cin.get(name,size).get();
-
if (!
cin)
-
{
-
cin.clear();
-
while (
cin.get()!=
'\n')
-
{
-
continue;
-
}
-
}
-
cout<<
"Enter your favorite program language:";
-
cin.get(pl,size).get();
-
cout<<
"Hello "<<name<<
", your favorite program language is "<<pl<<
endl;
另一個潛在的問題是,輸入字元可能比分配的空間長。如果輸入行包含的字元數比指定的多,則這get()和getline()將把餘下的字元留在輸入佇列中,而getline()還會設定失效位,並關閉輸入。
-
cout<<
"Enter your name:";
-
cin.getline(name,size);
-
if (!
cin)
-
{
-
cin.clear();
-
while (
cin.get()!=
'\n')
-
{
-
continue;
-
}
-
}
-
cout<<
"Enter your favorite program language:";
-
cin.getline(pl,size);
-
cout<<
"Hello "<<name<<
", your favorite program language is "<<pl<<
endl
5.混合輸入字串和數字
-
int age =
0;
-
char address[size] = {
0};
-
-
cout<<
"Enter your age:";
-
cin>>age;
-
cout<<
"Enter your address:";
-
cin.getline(address,size);
-
cout<<
"your age is "<<age <<
", your address is "<<address<<
endl;
上面的寫法有問題,會導致第二個輸入沒有機會。原因是:當cin讀取年齡時,將回車鍵生成的換行符留存了輸入佇列中,後面的cin.getline()看到換行符後,將認為是一個空行,並將一個空字串賦給address陣列。解決辦法為在cin>>age;後加cin.get();