天天看點

C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()

        在C++中,各種輸入方法還是不少的,而且各有所異,本文做一點簡要總結,主要涉及如下内容:cin、cin.get()、cin.getline()、getline()、gets()、getchar()。

        輸入原理簡述:

        程式的輸入都建有一個緩沖區,即輸入緩沖區。每次輸入過程是這樣的,當一次鍵盤輸入結束時會将輸入的資料存入輸入緩沖區,而cin函數直接從輸入緩沖區中取資料。正因為cin函數是直接從緩沖區取資料的,是以有時候當緩沖區中有殘留資料時,cin函數會直接取得這些殘留資料而不會請求鍵盤輸入。

        比如下面的例子:

void test_input()
{
	string str;
	cout<<"cin的測試:"<<endl;
	cin>>str;
	cout<<str<<endl;
	cin>>str;
	cout<<str<<endl;
}
           
C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()

        由于cin在遇到空格時,就會停止輸入,是以如果我在第一次輸入時,利用空格隔開兩個字元串,那麼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;
}
           
C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()

        各種輸入方法簡介:

        1、cin>>

        根據cin>>sth 中sth的變量類型讀取資料,這裡變量類型可以為int,float,char,char*,string等諸多類型。這一輸入操作,在遇到結束符(Space、Tab、Enter)就結束,且對于結束符,并不儲存到sth中。

void test_input()
{
	char ch1[10],ch2[10];
	cout<<"輸入兩個字元串:"<<endl;
	cin>>ch1;
	cin>>ch2;
	cout<<"兩個字元串分别為:"<<endl;
	cout<<ch1<<endl;
	cout<<ch2<<endl;
}
           
C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()

2、cin.get(字元數組名,接收長度,結束符)

其中結束符意味着遇到該符号結束字元串讀取,預設為ENTER,讀取的字元個數最多為(長度-1),因為最後一個為"\n"。要注意的是,cin.get()操作遇到結束符停止讀取,但并不會将結束符從緩沖區丢棄。cin.get()有如下幾種用法:

(1)接收一個字元ch=cin.get()或cin.get(char ch),二者等價,看兩個例子

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]沒有被删除。
C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()
  • 輸入a[Space]b[Enter],結果在輸出時,隻看到了a,輸出ASCII值時候分别為97 32(空格的ASCII值),這就說明cin.get()并不會舍棄Space,依然會将其讀取進去,并加以顯示等操作。 
C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()
  • 輸入a[Enter],輸出見下圖。在輸出a之後,第二次的輸出産生了換行的效果,而輸出的第二個ASCII值為10(Enter的ASCII值),這就進一步響應了前面說到的cin.get()遇到結束符并不會将之删除。  
C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()

(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,而不需要申請從鍵盤輸入,看一下結果,符合分析。
C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()
  • 輸入:zifu[Enter],此時輸入長度小于5就遇到了預設結束符Enter,則ch2中隻讀入“zifu”,要注意的是,輸入緩沖區裡面的Enter還在,是以接下來要讀入的ch1的内容将是Enter,而輸出時将看到換行,ASCII碼值為10,見下圖
C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()
  • 輸入:zi fuchuan[Enter],注意中間的空格,cin.get()對空格并不敏感,依然會讀入,故而ch2讀入的是“zi fu”,ch1讀入的是c
C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()

(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)就會申請從鍵盤輸入内容,如下所示:
C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()

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()時,适度設定其最大接受長度大一點。
C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()

4、getline(istream is,string str,結束符)

同樣,此處結束符為可選參數(預設依然為Enter)。然而,getline()與前面的諸多存在的差别在于,它string庫函數下,而非前面的istream流,所有調用前要在前面加入#include<string>。與之對應這一方法讀入時第二個參數為string類型,而不再是char*,要注意差別。另外,該方法也不是遇到空格就結束輸入的。

void test_input()
{
    string str;
    cout<<"請輸入string内容:"<<endl;
    getline(cin,str,'a');
    cout<<str<<endl;   
}
           
C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()
C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()

通過以上第二個圖還可以看出,這一方法隻有在遇到結束符(此處為‘a’)才結束,對空格甚至回車都不敏感。

5、gets(char *ch)

gets()方法同樣接受一個字元串,但是與getline()不同,它的參數為char*,而不是string,另外若定義char ch[n],長度為n,則樣注意輸入的字元串長度不要大于n,否則會報錯。同樣gets()對空格也不敏感。

void test_input()
{
    char ch[10];
    cout<<"請輸入char*内容:"<<endl;
    gets(ch);
    cout<<ch<<endl;    
}
           
C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()
C++基礎:各種輸入方法總結,cin、cin.get()、cin.getline()、getline()、gets()、getchar()

好吧,就到這裡吧,其實還有getchar()、getch()等,這裡就不一一贅述了。

繼續閱讀