C++ getline() 和 get()
字符串輸入問題
#include <iostream> using namespace std;int main() {const int Asize = 20;char name[Asize];char dessert[Asize];cout << "Enter your name:" <<endl;cin >> name;cout << "Enter your favorite dessert:" <<endl;cin >> dessert;cout << "I have some delicious " << dessert;cout << "for you, " << name << endl;return 0; }在沒有輸入你最喜歡的甜點的提示下,程序就把它顯示出來了,然后立即顯示最后一行。這是因為 cin 使用空白(空格、制表符和換行符)來確定字符串的結束位置,這意味著 cin 在獲取字符串數(shù)組輸入時只讀取空格前的一個單詞。讀取該單詞后,cin 將該字符串放到數(shù)組中,并自動在結尾添加空字符。
為了能讀取一行字符串輸入,cin 提供了一些面向行的類成員函數(shù):getline() 和 get()。這兩個函數(shù)都讀取一行輸入,直到到達換行符。然而,隨后?getline() 會丟棄換行符,而 get() 將換行符保留在輸入序列中。下面詳細介紹它們,首先介紹 getline()。
?
面向行的輸入:istream& getline(char *p, int n, char c)
getline() 函數(shù)讀取整行,它使用通過回車鍵輸入的換行符來確定輸入結尾。要調(diào)用這種方法,可以使用 cin.getline()。該函數(shù)有兩個參數(shù)。第一個參數(shù)是用來存儲輸入行的數(shù)組的名稱,第二個參數(shù)是要讀取的字符數(shù)量。如果參數(shù)是 20,那么最多可以讀取 19 個字符,余下的空間用于存儲自動在結尾處添加的空字符。如果在讀取 n-1 個字符之前遇到終止字符(第三個參數(shù)不寫,默認為 '\n' ),則提前結束。getline() 成員函數(shù)在讀取指定數(shù)目的字符或遇到換行符時停止讀取。
#include <iostream> using namespace std;int main() {const int Asize = 20;char name[Asize];char dessert[Asize];cout << "Enter your name:" <<endl;cin.getline(name, Asize);cout << "Enter your favorite dessert:" <<endl;cin.getline(dessert, Asize);cout << "I have some delicious " << dessert;cout << "for you, " << name << endl;return 0; }getline(cin, inputLine),其中 cin 是正在讀取的輸入流,而 inputLine 是接收輸入字符串的 string 變量的名稱。需要注意的是,它不是類方法。
#include <iostream> #include <string> // Header file needed to use string objects using namespace std; int main() {string name;string city;cout << "Please enter your name: ";getline(cin, name);cout << "Enter the city you live in: ";getline(cin, city);cout << "Hello, " << name << endl;cout << "You live in " << city << endl;return 0; }?
面向行的輸入:istream& get(char *p, int n, char c)
另一個名為 get() 的成員函數(shù),該函數(shù)有幾種變體。其中一種變體的工作方式和 getline() 類似,它們接受的參數(shù)相同,解釋參數(shù)的方式也相同,并且都讀取到行尾。情況1:當輸入的字符數(shù)小于 n 時遇到終結符,get() 并不再讀取并丟棄終結符,而是將其留在輸入隊列中。而 getline 函數(shù)將讀取這個字符但是不存進 p 所指的數(shù)組中,而是將其丟棄。當然,兩者都會在讀取的字符串后面自動加上 '\0'。假設我們連續(xù)兩次調(diào)用 get():
cin.get(name, Asize); cin.get(dessert, Asize); //dessert沒有內(nèi)容由于第一次調(diào)用后,換行符將留在輸入隊列中,因此第二次調(diào)用時看到第一個字符便是換行符。因此 get() 認為已到達行尾,而沒有發(fā)現(xiàn)任何可讀取的內(nèi)容。如果不借助于幫助,get() 將不能跨過該換行符。這時可以使用 get() 的另一種變體。使用不帶任何參數(shù)的 cin.get() 調(diào)用可讀取下一個字符(即使是換行符)。
cin.get(name, Asize); cin.get(); cin.get(dessert, Asize);另一種使用 get() 的方式是將兩個類成員函數(shù)拼接起來:
cin.get(name, Asize).get();之所以可以這樣做,是由于 cin.get(name, Asize) 返回一個 cin 對象,該對象隨后將被用來調(diào)用 get() 函數(shù)。同樣,下面的語句將輸入中連續(xù)的兩行分別讀入到數(shù)組 name1 和數(shù)組 name2 中,其效果與兩次調(diào)用 cin.getline() 相同:
cin.getline(name1, Asize).getline(name2, Asize); #include <iostream> using namespace std;int main() {const int Asize = 20;char name[Asize];char dessert[Asize];cout << "Enter your name:" <<endl;cin.get(name, Asize).get();cout << "Enter your favorite dessert:" <<endl;cin.get(dessert, Asize).get();cout << "I have some delicious " << dessert;cout << "for you, " << name << endl;return 0; }?
空格行和其他問題
當 getline() 或 get() 讀取空格時,將發(fā)生什么情況?當 get() 讀取空行后將設置失效位。這意味著接下來的輸入將被阻斷,但可以用下面的命令來恢復輸入:cin.clear()。
情況2:另一個潛在的問題是,輸入字符串可能比分配的空間要長。如果輸入行包含的字符數(shù)比指定的多,則 getline() 和 get() 將把余下的字符留在輸入隊列中,對 get() 而言,可以用另一條讀取函數(shù)來讀取留在輸入隊列中的數(shù)據(jù),也可以寫一段代碼將余下的字符清除。而 getline() 還會設置失效位,并關閉后面的輸入。同樣使用 cin.clear() 恢復輸入。
#include <iostream> using namespace std;int main() {cout << "What year was your house built?" <<endl;int year;cin >> year;cout << "What is its street address?" <<endl;char address[80];cin.getline(address, 80);cout << "Year built: " << year <<endl;cout << "Address: " << address <<endl;cout << "Done!" <<endl;return 0; }用戶根本沒有輸入地址的機會。問題在于,當 cin 讀取年份,將回車鍵生成的換行符留在了輸入隊列中。后面的 cin.getline() 看到換行符后,將認為是一個空行,并將一個空字符串賦予 address 數(shù)組。解決的方法是,在讀取地址之前先讀取并丟棄換行符。這可以通過使用沒有參數(shù)的 get() 和使用接受一個 char 參數(shù)的 get():
cin >> year; cin.get(); ??// or cin.get(ch);也可以利用表達式 cin >> year 返回 cin 對象,將調(diào)用拼接起來:
(cin >> year).get(); ??// ?or (cin >> year).get(ch); #include <iostream> using namespace std;int main() {cout << "What year was your house built?" <<endl;int year;(cin >> year).get();cout << "What is its street address?\n";char address[80];cin.getline(address, 80);cout << "Year built: " << year <<endl;cout << "Address: " << address <<endl;cout << "Done!" <<endl;return 0; }?
補充的一點:C++ 中 "\n"?與 endl 的區(qū)別
"\n" 表示內(nèi)容為一個回車符的字符串。std::endl 是流操作,輸出的作用和輸出 "\n" 類似,但略有區(qū)別。
std::endl 輸出一個換行符,并立即刷新緩沖區(qū)。
cout << endl; 相當于 std::cout << '\n'; std::fflush(stdout); 由于流操作符 << 的重載,對于 '\n' 和 "\n",輸出效果相同。對于有輸出緩沖的流(例如 cout、clog),如果不手動進行緩沖區(qū)刷新操作,將在緩沖區(qū)滿后自動刷新輸出。不過對于 cout 來說(相對于文件輸出流等),緩沖一般體現(xiàn)得并不明顯。但是必要情況下使用 endl 代替 "\n"是個好習慣。對于無緩沖的流(例如標準錯誤輸出流 cerr),刷新是不必要的,可以直接使用 "\n"。
總結
以上是生活随笔為你收集整理的C++ getline() 和 get()的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: STL泛型编程之迭代器
- 下一篇: C/C++ 指针和数组