@TOC
引言
在C++中,有很多的輸入方法,各有不同,今天給大家分享一篇關於cin、cin.get()、cin.getline()、getline()、gets、getchar()、peek()的文章。
參照原文鏈接:https://blog.csdn.net/qq_40725780/article/details/81032700
輸入原理簡述
程序的輸入都建有一個緩衝區,即輸入緩衝區。每次輸入過程是這樣的,當一次鍵盤輸入結束時會將輸入的數據存入輸入緩衝區,而cin函數直接從輸入緩衝區中取數據。正因爲cin函數是直接從緩衝區取數據的,所以有時候當緩衝區中有殘留數據時,cin函數會直接取得這些殘留數據而不會請求鍵盤輸入。
比如下面的例子:
void test_input()
{
string str;
cout<<"cin的測試:"<<endl;
cin>>str;
cout<<str<<endl;
cin>>str;
cout<<str<<endl;
}
由於cin在遇到空格/tab時,就會停止輸入,所以如果我在第一次輸入時,利用空格隔開兩個字符串,那麼cin在第一次取的時候,只會讀取前一個字符串,到空格結束,此時緩衝區還保留着前面輸入的第二個字符串,那麼第二次cin就會直接從緩衝區取殘留數據,而不會請求輸入。
當然對於以上的情況,也有解決的方案,那就是在第二次調用cin>>str之前通過cin.sync()來清空輸入緩衝區,看一下下面的例子,此處不贅述:
void test_input()
{
string str;
cout<<"cin的測試:"<<endl;
cin>>str;
cin.sync();
cout<<str<<endl;
cin>>str;
cout<<str<<endl;
}
各種輸入方法簡介
1、cin>>
根據cin>>sth 中sth的變量類型讀取數據,這裏變量類型可以爲int,float,char,char*,string等諸多類型。這一輸入操作,在遇到結束符(Space、Tab、Enter)就結束,且對於結束符,並不保存到變量中。注意:最後一個enter也在緩衝區。
void test_input()
{
char ch;
char ch1[10],ch2[10];
cout<<"輸入兩個字符串:"<<endl;
cin>>ch1;
cin>>ch2;
cout<<"兩個字符串分別爲:"<<endl;
cout<<ch1<<endl;
cout<<ch2<<endl;
cin.get(ch);
cout << (int)ch << endl; //輸出10,爲最後一個enter輸入
}
2、cin.get(字符數組名,接收長度,結束符)
其中結束符意味着遇到該符號結束字符串讀取,默認爲enter,讀取的字符個數最多爲(長度 - 1),因爲最後一個爲’\0’。要注意的是,cin.get()操作遇到結束符停止讀取,但並不會將結束符從緩衝區丟棄。cin.get函數有如下幾種聲明:
int get();
istream& get(char& c);
istream& get(char* s, streamsize n);
istream& get(char* s, streamsize n, char delim);
istream& get(streambuf& sb);
istream& get(streambuf& sb, char delim);
(1)接收一個字符ch=cin.get()或cin.get(char ch),二者等價,看兩個例子
cin.get()存在的基本目的,我認爲就是爲了從c移植到c++的時候,直接用cin.get()代替getchar(),也正因因此,cin.get()的返回值跟其它cin.get成員函數返回cin對象不同,跟getchar()一樣返回int。所以cin.get()和C語言的getchar()沒什麼區別。
void test_input()
{
char ch1,ch2;
cout<<"請輸入兩個字符:"<<endl;
cin.get(ch1);//或ch1 = cin.get();
cin.get(ch2);
cout<<ch1<<" "<<ch2<<endl;
cout<<(int)ch1<<" "<<(int)ch2<<endl;
}
來看幾組測試:
連續輸入ab[enter],結果正常,ch1,ch2分別讀取了a、b,將其輸出,然後在輸出其ASCII值。要注意的是,以上輸入並讀取後,緩衝區中依然存在[Enter]沒有被刪除。
輸入a[Space]b[Enter],結果在輸出時,只看到了a,輸出ASCII值時候分別爲97 32(空格的ASCII值),這就說明cin.get()並不會捨棄Space,依然會將其讀取進去,並加以顯示等操作。
輸入a[Enter],輸出見下圖。在輸出a之後,第二次的輸出產生了換行的效果,而輸出的第二個ASCII值爲10(Enter的ASCII值),這就進一步響應了前面說到的cin.get()遇到結束符並不會將之刪除。
(2)接收一定長度的字符串cin.get(字符數組名,接收長度,結束符),結束符爲可選參數,默認爲Enter,可以接受Space 、Tab,對於結束符的處理要注意,結束符並不會丟掉,同樣看幾個例子。
對於如下代碼,所做的操作時,在不遇到enter時最多讀入(6-1)=5個字符到ch2中,然後讀入下一個字符到ch1中,顯示ch2,ch1以及其ASCII碼值。附上幾組測試:
void test_input()
{
char ch1,ch2[10];
cout<<"請輸入字符串:"<<endl;
cin.get(ch2,6);//在不遇到結束符的情況下,最多可接收6-1=5個字符到ch2中,注意結束符爲默認Enter
cin.get(ch1);//或ch1 = cin.get();
cout<<ch2<<endl;
cout<<ch1<<"\n"<<(int)ch1<<endl;
}
輸入:zifuchuan[Enter],由於輸入長度大於(6-1)=5,所以會首先讀入“zifuc”到ch1,此時“huan”仍在緩衝區,當執行cin.get(ch1)會直接從緩衝區讀入h,而不需要申請從鍵盤輸入,看一下結果,符合分析。
輸入:zifu[Enter],此時輸入長度小於5就遇到了默認結束符Enter,則ch2中只讀入“zifu”,要注意的是,輸入緩衝區裏面的Enter還在,所以接下來要讀入的ch1的內容將是Enter,而輸出時將看到換行,ASCII碼值爲10,見下圖
輸入:zi fuchuan[Enter],注意中間的空格,cin.get()對空格並不敏感,依然會讀入,故而ch2讀入的是“zi fu”,ch1讀入的是c
假如:
#include <iostream>
using namespace std;
int main()
{
char ch1, ch2[10];
cout << "請輸入字符串:" << endl;
cin.get(ch2, 13);//在不遇到結束符的情況下,最多可接收13-1=12個字符到ch2中,注意結束符爲默認Enter
cin.get(ch1);//或ch1 = cin.get();
cout << ch2 << endl;
cout << ch1 << "\n" << (int)ch1 << endl;
return 0;
}
輸入:123456789(enter)
輸出:
輸入:1234567890(enter)
則VS2015運行報錯!因爲ch2[10]用cin.get最多接受9個字符,最後一個是’\0’。但g++ 5.4.0正常(說明沒有對下標越界做檢查)。
還有一點需要注意的是,cin.get(字符數組名,接收長度,結束符),當一開始第一個輸入字符(即前面無其他任何字符)就遇到結束符情況下,緩衝區中將無該結束符。
例:
#include <iostream>
using namespace std;
int main()
{
char ch[5], ch2;
cin.get(ch, 3); //默認結束符'\n',此處直接(enter)
cin.get(ch2); //緩衝區無'\n'
cout << ch2 << ' ' << (int)ch2 << endl; //VS2015 輸出-52, g++ 5.4.0 輸出0
return 0;
}
以上程序如果輸入1(enter),緩衝區將正常保留\n,輸出如下:
再來一例:
#include <iostream>
using namespace std;
int main()
{
char ch[5], ch2;
cin.get(ch, 3, 'a');// 結束符爲'a',直接輸入a(enter)
cin.get(ch2);
cout << ch2 << ' ' << (int)ch2 << endl;
return 0;
}
輸出:
如果輸入1a(enter),'a’將在緩衝區,輸出如下:
cin.get(ch2)和ch2 = cin.get()小區別:
#include <iostream>
using namespace std;
int main()
{
char ch[5], ch2;
cin.get(ch, 3, 'a'); //此處輸入a(enter)
ch2 = cin.get(); //注意與cin.get(ch2)不同
cout << ch2 << ' ' << (int)ch2 << endl;
return 0;
}
(3)cin.get( ),注意此時沒有參數,可用於捨棄輸入流中的不需要的字符,或者捨棄回車,彌補cin.get(字符數組名,字符數目,結束符)的不足。對(2)中的代碼加入一句話cin.get()如下:
void test_input()
{
char ch1,ch2[10];
cout<<"請輸入字符串:"<<endl;
cin.get(ch2,6);//在不遇到結束符的情況下,最多可接收6-1=5個字符到ch2中
cin.get();//注意:前面兩句可以寫到一塊:cin.get(ch2,6).get();
cin.get(ch1);//或ch1 = cin.get();
cout<<ch2<<endl;
cout<<ch1<<"\n"<<(int)ch1<<endl;
}
前面遇到的一個狀況是,輸入字符後,其結束符(如默認的Enter)會保留在緩衝區中,當下次讀入時,又會再讀入,此時就可以用到cin.get()獨釣輸入緩衝區不需要的字符,如:輸入:zi[Enter],由於遇到結束符,所以ch2內容爲zi,此時輸入緩衝區還存在着[Enter],但cin.get()將其捨棄掉之後,cin.get(ch1)就會申請從鍵盤輸入內容,如下所示:
3、cin.getline(字符數組名,接收長度,結束符)
其用法與cin.get(字符數組名,接收長度,結束符)極爲類似。cin.get()當輸入的字符串超長時,不會引起cin函數的錯誤,後面若有cin操作,會繼續執行,只是直接從緩衝區中取數據。但是cin.getline()當輸入超長時,會引起cin函數的錯誤,後面的cin操作將不再執行。如下代碼:
void test_input()
{
char ch1,ch2[10];
cout<<"請輸入字符串:"<<endl;
cin.getline(ch2,6);//在不遇到結束符的情況下,最多可接收6-1=5個字符到ch2中
cin>>ch1;
cout<<ch2<<endl;
cout<<ch1<<"\n"<<(int)ch1<<endl;
}
測試:如下圖,輸入zifuchuan[Enter],長度大於最大長度5,就會導致cin函數錯誤,其後既沒有像cin.get()一樣直接從輸入緩衝區直接讀數據,也沒有從鍵盤輸入。所以此處可以注意,考慮在用cin.getline()時,適度設置其最大接受長度大一點。
假如:
#include <iostream>
using namespace std;
int main()
{
char ch1, ch2[6]; // 最多可接收5個,最後一個'\0'
cout << "請輸入字符串:" << endl;
cin.getline(ch2, 8);//在不遇到結束符的情況下,最多可接收8-1=7個字符到ch2中
cin >> ch1;
cout << ch2 << endl;
cout << ch1 << "\n" << (int)ch1 << endl;
return 0;
}
輸入:123456(enter) VS將會報錯,g++正常。說明VS對數組下標進行了檢查。
cin.get()每次讀取一整行並把由Enter鍵生成的換行符留在輸入隊列中,然而cin.getline()每次讀取一整行並把由Enter鍵生成的換行符拋棄,比如:
#include <iostream>
using namespace std;
int main() {
cout << "Enter your name:";
char name[15];
cin.get(name, 15); // 輸入abc(enter)
//cin.getline(name, 15);
cout << "name:" << name << endl;
char ch;
cin.get(ch); //因爲cin.get不會丟棄最後一個換行符,所以此處ch讀取換行符
cout << (int)ch << endl; //輸出10 '\n'的ASCII碼值
cout << "\nEnter your address:";
char address[15];
cin.getline(address, 15); //輸入123(enter)
//cin.get(address, 15);
cout << "address:" << address << endl;
cin.get(ch);// 因爲cin.getline丟棄最後一個換行符,所以此處重新從鍵盤輸入a(enter)
cout << (int)ch << endl; //輸出97 'a'的ASCII碼值
cin.get(ch); // cin.get不會丟棄最後一個換行符,所以此處讀取上一步輸入的保留在緩衝區的換行符
cout << (int)ch << endl; // 輸出10 '\n'的ASCII碼值
return 0;
}
#include <iostream>
using namespace std;
int main() {
cout << "Enter your name:";
char name[15];
cin.get(name, 15); // 輸入abc(enter)
//cin.getline(name, 15);
cout << "name:" << name << endl;
char ch;
cin.get(ch); //因爲cin.get不會丟棄最後一個換行符,所以此處ch讀取換行符
cout << (int)ch << endl; //輸出10 '\n'的ASCII碼值
cout << "\nEnter your address:";
char address[15];
cin.getline(address, 15); //輸入123(enter)
//cin.get(address, 15);
cout << "address:" << address << endl;
cin.get(ch);// 因爲cin.getline丟棄最後一個換行符,所以此處重新從鍵盤輸入a(enter)
cout << (int)ch << endl; //輸出97 'a'的ASCII碼值
cin.get(ch); // cin.get不會丟棄最後一個換行符,所以此處讀取上一步輸入的保留在緩衝區的換行符
cout << (int)ch << endl; // 輸出10 '\n'的ASCII碼值
return 0;
}
4、gets()
gets()方法接受一個字符串,它的參數爲char*,而不是string,另外若定義char ch[n],長度爲n,需要注意輸入的字符串長度不要大於n,否則會報錯,gets()對空格也不敏感,注意,gets()在vs2017中不能使用,應使用gets_s()代替。
5、getline(istream is,string str,結束符)
同樣,此處結束符爲可選參數(默認依然爲enter)。然而,getline()與前面的諸多存在的差別在於,它string庫函數下,而非前面的istream流,所有調用前要在前面加入#include。與之對應這一方法讀入時第二個參數爲string類型,而不再是char*,要注意區別。另外,該方法也不是遇到空白字符(tab, space, enter(當結束符不是默認enter時))就結束輸入的,且會丟棄最後一個換行符。
#include <iostream>
#include <string>
using namespace std;
int main() {
char ch;
string str;
cout << "請輸入string內容:" << endl;
getline(cin, str); //輸入:abc(space)(space)d(enter)
//getline(cin, str, 'a');
cout << str << endl;
cin.get(ch); //因爲丟棄了最後一個換行符,所以此處從鍵盤輸入b
cout << (int)ch << endl; //輸出:98 'b'的ASCII碼值
return 0;
}
#include <iostream>
#include <string>
using namespace std;
int main() {
char ch;
string str;
cout << "請輸入string內容:" << endl;
//getline(cin, str);
getline(cin, str, 'a'); //輸入:string(enter)strinabc,遇到結束符'a'停止讀取
cout << str << endl; //輸出string(enter)strin
cin.get(ch); //將緩衝區中'a'丟棄,讀取'a'之後的'b'
cout << (int)ch << endl; //輸出:98 'b'的ASCII碼值
return 0;
}
6、getline和cin.getline區別
cin.getline()當輸入超長時,會引起cin函數的錯誤,後面的cin操作將不再執行。
#include <iostream>
using namespace std;
int main()
{
char ch, a[20];
cin.getline(a, 5);// 此處輸入12345(enter)
cin >> ch;
cout << a << endl;
cout << (int)ch << endl;
return 0;
}
輸出:
這裏的ch並沒有讀取緩衝區中的5,而是返回了-52(VS)/0(g++),這裏其實cin>>ch語句沒有執行,是因爲cin出錯了!我們經常會看到程序中會出現cin.clear(),cin.ignore(), cin.fail()等函數。這些函數都是與cin的錯誤處理有關的。這一節我們來分析一下cin的錯誤處理機制,並且學習幾個重要的函數:cin.fail(), cin.bad(), cin.good(), cin.clear(), cin.ignore()等。程序執行時有一個標誌變量來標誌輸入的異常狀態,其中有三位標誌位分別用來標誌三種異常信息,他們分別是:failbit,eofbit,badbit。
ios類定義了這四個常量badbit, eofbit, failbit, goodbit,其實這四個標誌常量就是取對應標誌位的掩碼,也即輸入的四種異常情況!
以上四個常量在g++對應的取值爲:
ios::badbit 001 輸入(輸出)流出現致命錯誤,不可挽回
ios::eofbit 010 已經到達文件尾
ios::failbit 100 輸入(輸出)流出現非致命錯誤,可挽回
ios::goodbit 000 流狀態完全正常, 各異常標誌位都爲0
我們可以用輸出語句來驗證這幾個常量的值:
cout << ios:: failbit << endl;
cout << ios:: eofbit << endl;
cout << ios:: badbit << endl;
cout << ios:: goodbit << endl;
g++輸出的結果爲:
VS下輸出:
【注意】它們不是failbit、badbit、eofbit、goodbit這四個標記位的存貯變量,而是四個標誌四種異常狀態的常量,其實他們就相當於取對應狀態標誌位的掩碼。如果標誌變量爲flag,則flag & failbit 就取得fail標誌位。
6、getchar()
getchar是讀入函數的一種。它從標準輸入裏讀取下一個字符,相當於getc(stdin)。返回類型爲int型,爲用戶輸入的ASCII碼或EOF。
int getchar(void)
{
static char buf[BUFSIZ];
static char* bb=buf;
static int n=0;
if(n==0)
{
n=read(0,buf,BUFSIZ);
bb=buf;
}
return(--n>=0)?(unsigned char)*bb++:EOF;
}
getchar由宏實現:#define getchar() getc(stdin)。getchar有一個int型的返回值。當程序調用getchar時.程序就等着用戶按鍵。用戶輸入的字符被存放在鍵盤緩衝區中。直到用戶按回車爲止(回車字符也放在緩衝區中)。當用戶鍵入回車之後,getchar纔開始從stdio流中每次讀入一個字符。getchar函數的返回值是用戶輸入的字符的ASCII碼,若文件結尾(End-Of-File)則返回-1(EOF),且將用戶輸入的字符回顯到屏幕。如用戶在按回車之前輸入了不止一個字符,其他字符會保留在鍵盤緩存區中,等待後續getchar調用讀取。也就是說,後續的getchar調用不會等待用戶按鍵,而直接讀取緩衝區中的字符,直到緩衝區中的字符讀完後,纔等待用戶按鍵。
例如:
#include<stdio.h>
#include<conio.h>
main(void)
{
int c;
int a;
a=getchar();
if (EOF!=a)
printf("%c",a);
while((c=getchar())!='\n')//c接收的值是輸入第一個字符後按下的回車換行符'\n',c是不會顯示的
{
if (EOF==a)
break;
printf("%d",c);
}
getchar();
}
8、peek()
cin.peek()的返回值是一個char型的字符,其返回值是指針指向的當前字符,但它只是觀測
指針停留在當前位置並不後移;如果要訪問的字符是文件結束符,則函數值是EOF(-1)
例如:
編寫一個程序,要求用戶輸入一串整數和任意數目的空格,這些整數必須位於同一行中,但允許出現在該行的任意位置,當用戶按下回車鍵時,數據輸入結束,程序將輸入的整數求和顯示。
#include<iostream>
using namespace std;
int main(){
int sum=0;
int c;
while(cin>>c){
sum+=c;
while(cin.peek()==' '){ //屏蔽空格
cin.get();
}
if(cin.peek()=='\n'){
break;
}
}
cout<<sum<<endl;
return 0;
}
運行結果:
關於異常標誌的函數:
1、iostate ios::rdstate();
取標誌變量的值,我們可以用該函數取得整個標誌變量的值,再與前面定義的標誌位常量相與就可以獲得對應標誌位的狀態。如:
void TestFlags( ios& x ) // 獲得x流的三個標誌位狀態
{
cout << ( x.rdstate( ) & ios::badbit ) << endl;
cout << ( x.rdstate( ) & ios::failbit ) << endl;
cout << ( x.rdstate( ) & ios::eofbit ) << endl;
cout << endl;
}
2、bool ios::fail()const;
1 or true if rdstate & failbit is nonzero, otherwise 0 or false. (引用msdn)
其中rdstate即通過rdstate()取得的標識變量的值,與failbit相與,即取得failbit標誌位的值,如果結果非零則放回true,否則返回false。即該函數返回failbit的狀態,將標誌位狀態通過bool值返回。
3、bool ios::bad() const;
1 or true if rdstate & badbit is nonzero; otherwise 0. (引用msdn)
與fail()相似。
4、bool ios::good()const;
1 or true if rdstate == goodbit (no state flags are set), otherwise, 0 orfalse. (引用msdn)
改函數取goodbit的情況,即三個標誌位都0(即沒有任何異常情況)時返回true,否則返回false。
5、voidios::clear(iostate _State=goodbit);
該函數用來重置標識變量,_State是用來重置的值,默認爲goodbit,即默認時將所有標誌位清零。用戶也可以傳進參數,如:clear(failbit),這樣就將標識變量置爲failbit(即:001)。
我們一般是用它的默認值,當cin出現異常,我們用該函數將所有標誌位重置。如果cin出現異常,沒有重置標誌的話沒法執行下一次的cin操作。如上一節的程序2的測試二爲什麼第二次輸入操作沒有執行?程序8中 cin>>ch 爲什麼沒有執行?都是這個原因!!!
所以經常在程序中使用 cin.clear(), 爲了重置錯誤標誌!
6、另外還有一個函數 void ios::setstate(iostate_State);
這個函數也是用來設置標識變量的,但與clear()不同。clear()是將所有標誌清零,在置以參數新的標誌。而該函數不清零其他的標誌,而只是將參數對應的標誌位置位。這個函數不是經常使用,這裏不再贅述。
在搞清楚了這幾個函數後,對cin輸入操作的錯誤處理就有了比較深的瞭解了。下面我們回過頭來看看上一節程序8的測試,因爲第一次用getline()讀取字符串超長,所以導致出現異常,大家可以查看一下標誌位來驗證一下!所以會導致後面的 cin>>ch 語句沒有執行。那我們利用前面學習的clear()函數來強制重置錯誤標誌,看看會出現什麼情況呢?
#include<iostream>
using namespace std;
int main ()
{
char ch, str[20];
cin.getline(str, 5);
cout<<"flag1:"<<cin.good()<<endl; // 查看goodbit狀態,即是否有異常
cin.clear(); // 清除錯誤標誌
cout<<"flag1:"<<cin.good()<<endl; // 清除標誌後再查看異常狀態
cin>>ch;
cout<<"str:"<<str<<endl;
cout<<"ch :"<<ch<<endl;
return 0;
}
測試輸入:
12345[Enter]
輸出:
flag1:0 // good()返回false說明有異常
flag2:1 // good()返回true說明,clear()已經清除了錯誤標誌
str:1234
ch :5
【分析】程序執行結束還是隻執行了一次讀操作,cin>>ch還是沒有從鍵盤讀取數據,但是與程序8中不同,這裏打印了ch的值爲’5’,而且在cin>>ch之前已經清楚了錯誤標誌,也就是cin>>ch的讀操作實際上執行了。這就是前面講的cin讀取數據的原理:它是直接從輸入緩衝區中取數據的。此例中,第一次輸入"12345",而getline(str, 5)根據參數’5’只取緩衝區中的前4個字符,所以str取的是"1234",而字符’5’仍在緩衝區中,所以cin>>ch直接從緩衝區中取得數據,沒有從鍵盤讀取數據!
也就是當前一次讀取數據出錯後,如果緩衝區沒有清空的話,重置錯誤標誌還不夠!要是能將緩衝區的殘留數據清空了就好了哦!下面我們再來看一個很重要的函數!
7、
basic_istream&ignore(streamsize _Count = 1, int_type _Delim =
traits_type::eof()); function: Causes a number of elements to be
skipped from the current readposition. Parameters:
_Count, The number of elements to skip from the current read position.
_Delim, The element that, if encountered before count, causes ignore to returnand allowing all elements after _Delim to be read. (引用msdn)
這個函數用來丟棄輸入緩衝區中的字符,第一參數定義一個數,第二個參數定義一個字符變量。下面解釋一下函數是怎樣執行的:函數不停的從緩衝區中取一個字符,並判斷是不是_Delim,如果不是則丟棄並進行計數,當計數達到_Count退出,如果是則丟棄字符退出。例:cin.ignore(5, ‘a’); 函數將不斷從緩衝區中取一個字符丟棄,直到丟棄的字符數達到5或者讀取的字符爲’a’。下面我們看個程序例子:
#include <iostream>
using namespace std;
int main()
{
char ch;
cin.ignore(5, 'a');
cin.get(ch);
cout << (int)ch << endl;
return 0;
}
1.當輸入:123456(enter)時,VS和g++都輸出54(字符’6’的ASCII碼)。如下所示:
2.當輸入:b(enter)b(enter) b(enter) 時,VS和g++都輸出10(即最後一個enter的ASCII碼)。說明cin.ignore()會讀取enter,如下所示:
3.但當輸入:1234(enter)ab(enter)時,VS輸出97(‘a’),g++輸出98(‘b’)。
也就是VS中cin.ignore()將第一個enter讀取了,但g++中cin.ignore()未讀取第一個enter,而是讀取了第一個enter之後的’a’。
丟棄一個字符:
我們看看這個函數的默認值,第一個參數默認爲1,第二個參數默認爲EOF。所以cin.ignore()就是丟棄緩衝區中的第一個字符,這在程序中也是比較常用的!
#include <iostream>
using namespace std;
int main()
{
char c1, c2;
cin.get(c1);
cin.ignore(); // 用該函數的默認情況,丟棄一個字符,即上次輸入結束的回車符
cin.get(c2);
cout<<c1<<" "<<c2<<endl; // 打印兩個字符
cout<<(int)c1<<" "<<(int)c2<<endl; // 打印這兩個字符的ASCII值
return 0;
}
測試一輸入:
a[Enter]
b[Enter]
輸出:
a
b
97 98
【分析】這樣程序就正常了!
清空整個緩衝區:
其實該函數最常用的方式是這樣的,將第一個參數設的非常大,將第二個參數設爲’\n’,這樣就可以緩衝區中回車符中的所有殘留數據,因爲一般情況下前面輸入殘留的數據是沒有用的,所以在進行新一次輸入操作前將緩衝區中所有數據清空是比較合理。
如:cin.ignore(1024, '\n');
或者:cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');