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