1. 程式人生 > >C++ 讀取鍵盤輸入(cin/cin.getline()/cin.get()/cin.clear())

C++ 讀取鍵盤輸入(cin/cin.getline()/cin.get()/cin.clear())




1.cin

C++ 使用cin可以方便的讀取鍵盤輸入的字元,例如:


  
  1. //test input
  2. #include <iostream>
  3. int main()
  4. {
  5. using namespace std;
  6. const int size = 20;
  7. char
    name[size];
  8. char pl[size]; //program language
  9. cout<< "Enter your name:";
  10. cin>>name;
  11. cout<< "Enter your favorite program language:";
  12. cin>>pl;
  13. cout<< "Hello "<<name<< ", your favorite program language is "<<pl<< endl;
  14. return 0;
  15. }


首先,每個輸入我們只輸入一個單詞,如下:

但如果我們在第一個輸入時填寫兩個以上單詞:

可以發現,第二個輸入還沒來得及響應,就已經都顯示出來了。

原因是:cin通過使用空白(空格、製表符和換行符)來定字串的界。這意味著cin在讀取字元陣列輸入時只讀取一個單詞,讀取該單詞後,cin將該字串放一陣列中,並自動結尾新增空字元。另外,cin也沒有很好的控制元件輸入的字元數,即輸入字元數大於陣列大小的情況沒有處理。

2.cin.getline()

基於上面的情況,使用cin.getline()讀取一行資料。

cin.getline()函式讀取整行,它使用通過回車鍵輸入的換行符來確定輸入結尾。該函式有兩個引數。第一個引數是用來儲存輸入行的陣列的名稱,第二個引數是要讀取的字元數(包括空字元),cin.getline()成員函式在讀取指定數目的字元或遇到換行符時停止讀取

如下:


  
  1. cout<< "Enter your name:";
  2. cin.getline(name,size);
  3. cout<< "Enter your favorite program language:";
  4. cin.getline(pl,size);
  5. cout<< "Hello "<<name<< ", your favorite program language is "<<pl<< endl;

現在再來獲得多個單詞的輸入:

發現就正常了。需要注意的是,cin.getline()丟棄了換行符。

3.cin.get()

get()函式有好幾種變體,其中有一種與getline()完全相同的引數,但該函式不再讀取並丟棄換行符(不讀取意味著換行符還在輸入佇列中):


  
  1. cout<< "Enter your name:";
  2. cin.get(name,size);
  3. cout<< "Enter your favorite program language:";
  4. cin.get(pl,size);
  5. cout<< "Hello "<<name<< ", your favorite program language is "<<pl<< endl;

嘗試輸入:

發現並不好使,原因是由於第一次呼叫後,換行符將留存輸入佇列中,因此第二次呼叫時看到的第一個字元為換行符。因此get認為已經到達行尾,而沒有發現任何可讀取的內容。get()(不帶任何引數的變體)可以讀取下一個字元(包括換行符)。因此可以:


  
  1. cin.get(name,size).get();
  2. 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:”;  


  
  1. cout<< "Enter your name:";
  2. cin.get(name,size).get();
  3. if (! cin)
  4. {
  5. cin.clear();
  6. while ( cin.get()!= '\n')
  7. {
  8. continue;
  9. }
  10. }
  11. cout<< "Enter your favorite program language:";
  12. cin.get(pl,size).get();
  13. cout<< "Hello "<<name<< ", your favorite program language is "<<pl<< endl;
另一個潛在的問題是,輸入字元可能比分配的空間長。如果輸入行包含的字元數比指定的多,則這get()和getline()將把餘下的字元留在輸入佇列中,而getline()還會設定失效位,並關閉輸入。


  
  1. cout<< "Enter your name:";  
  2. cin.getline(name,size);  
  3. if (! cin)
  4. {
  5.      cin.clear();
  6.      while ( cin.get()!= '\n')
  7.     {
  8.          continue;
  9.     }
  10. }
  11. cout<< "Enter your favorite program language:";  
  12. cin.getline(pl,size);  
  13. cout<< "Hello "<<name<< ", your favorite program language is "<<pl<< endl

5.混合輸入字串和數字


  
  1. int age = 0;
  2. char address[size] = { 0};
  3. cout<< "Enter your age:";
  4. cin>>age;
  5. cout<< "Enter your address:";
  6. cin.getline(address,size);
  7. cout<< "your age is "<<age << ", your address is "<<address<< endl;
上面的寫法有問題,會導致第二個輸入沒有機會。原因是:當cin讀取年齡時,將回車鍵生成的換行符留存了輸入佇列中,後面的cin.getline()看到換行符後,將認為是一個空行,並將一個空字串賦給address陣列。解決辦法為在cin>>age;後加cin.get();