cin詳解(get()、getline()、clear()、sync())

簡述

在C中,輸入輸出用scanf和printf,在輸入數據的同時還需說明數據的類型,若是輸入數據較多,那就很麻煩,而C++中也有類似的東西cin和cout,它們來自C++的一個名叫」 iostream」的類庫。ios

iostream是由istream(輸入流)和ostream(輸出流)派生。因此在iostream中就有了輸入和輸出的相關對象:markdown

  • cin:標準輸入(standard input)的istream類對象,cin使咱們能夠從設備讀取數據。
  • cout:標準輸出(standard output)的ostream類對象。對應於標準輸出流,默認狀況下是顯示器。這是一個被緩衝的輸出,能夠被重定向。
  • cerr:標準錯誤流,用於顯示錯誤消息。默認狀況下被關聯到標準輸出流,但它不被緩衝,也就說錯誤消息能夠直接發送到顯示器,而無需等到緩衝區或者新的換行符時,才被顯示。通常狀況下不被重定向。

cout與cerr的區別:cout的輸出能夠重定向到一個文件中,而cerr必須輸出在顯示器上。學習

暫時先介紹這些,如下主要介紹cin中get()、getline()、clear()、sync()的用法。ui

get()

首先看看get(),它是一個讀取單個字符的方法。字符變量 = cin.get(),至關於cin.get(字符變量)。spa

#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    char str;
    str = cin.get();      //讀取單個字符,在屏幕輸入,至關於cin.get(str);
    cout << str << endl;  //輸出剛剛載入的單個字符
    system("pause");      //進行暫停,不然會一閃而過

    return 0;
}

運行程序後:指針

輸入:a
輸出:acode

但當輸入的爲多個英文字符時,那又會如何呢?對象

輸入:abcd
輸出:aci

結論:get()只能讀取第一個字符。get

#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    char str1;
    char str2;
    str1 = cin.get();  //讀取單個字符,在屏幕輸入
    str2 = cin.get();
    cout << str1 << str2 << endl;  //輸出剛剛載入的單個字符
    system("pause");  //進行暫停,不然會一閃而過

    return 0;
}

運行程序後:

輸入:abcd
輸出:ab

既然get()是讀取第一個字符,那str2爲何不也是a呢?

原理以下:

在cin這個對象裏,有一個儲存字符的流,能夠想象成緩衝區,事實上是cin裏封裝的一個東西。當咱們在程序上輸入字符後,對象cin得到了咱們輸入的字符。例如得到abcd,而後再經過.get()把流裏面的第一個字符去掉,賦給str1,這時,cin裏儲存的流的數據爲bcd,而str1則得到了a。當咱們再次運行str2 = cin.get()時,同理把cin裏流的數據的b拿出來給了str2,此後,cin裏面的流的數據爲cd,而str2則爲b,因此最後輸出時,便能輸出ab了。

還有個補充,究竟何時才輸入數據呢?咱們能夠再經過上面的代碼進行嘗試,咱們輸入單個字母’a’,而後按回車,發現並無輸出數據,而是再等待一次輸入數據,咱們再輸入字母’b’,按回車後便輸出ab了。相信到這裏,你們都應該明白了,由於當咱們第一次輸入a後,經過str1 = cin.get()使cin裏的流沒有數據,清空了。因此到第二次要再賦給str2值時,它找不到數據,要從新再輸入數據。由此來看能夠知道,當cin裏的流數據清空時,便須要從新輸入才能賦值。

而get()還有個用法:

#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    char str1;
    char str2;
    str1 = cin.get();  //讀取單個字符,在屏幕輸入
    cin.get();
    str2 = cin.get();
    cout << str1 << str2 << endl;  //輸出剛剛載入的單個字符
    system("pause");

    return 0;
}

運行程序後:

輸入:abcd
輸出:ac

程序中有3個get(),由此可知,當空回調get()時,get()便自動在cin中的流數據中刪除一個字母,起了一個刪除做用。

getline()

對get()有了必定了解以後,對getline()的學習就能夠更快了,原理是一致的,可是getline()則是獲取一整行文本。

原型:getline(char *line, int size, char=’/n’)

參數一:字符指針
參數二:字符長度
參數三:結束標識符。

#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    char str[200];
    cin.getline(str, sizeof(str));  //第三個不輸入,默認回車爲結束標符
    cout << str << endl;  //輸出
    system("pause");

    return 0;
}

這樣,咱們輸入多個英文或數字,而後按回車,就會輸出剛剛輸出的東西了。

接下來,咱們討論第三個參數的做用。

#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    char str[200];
    cin.getline(str, sizeof(str), 'X'); //以單個英文字母'X'做爲終止標識符
    cout << str << endl; //輸出
    system("pause");

    return 0;
}

當咱們輸入多個數字或者字母時,例如:

輸入:abcdeX(回車) 輸出:abcde
輸入:aXbcde(回車) 輸出:a
輸入:Xabcde(回車) 輸出:

這樣X便成了終止符,如上可知:當遇到第一個結束符標誌時,就結束,輸出其前面的全部字符。其原理和get()同樣。或許咱們能夠像get()那樣嘗試一下:

#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    char str1[200];
    char str2[200];
    cin.getline(str1, sizeof(str1), 'X'); //以單個英文字母'X'做爲終止標識符
    cin.getline(str2, sizeof(str2), 'Y'); //以單個英文字母'Y'做爲終止標識符
    cout << "第一行是:" << str1 << endl; //輸出
    cout << "第二行是:" << str2 << endl;
    system("pause");

    return 0;
}

輸入:abcdXXXefghYYYigkl(回車)
輸出: 第一行:abcd 第二行:XXefgh

如上可知,當遇到第一個結束符’X’結束輸出abcd,以後遇到第一個結束符’Y’結束輸出XXefgh。

clear()

接下來談談clear()的做用,第一次看到這東西,不少人覺得就是清空cin裏面的數據流,而實際上卻與此相差甚遠,首先看看如下代碼:

#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    int a;
    cin >> a;
    ios::iostate state = cin.rdstate();
    cout << state << endl;
    if (state == ios::goodbit)
    {
        cout << "輸入數據的類型正確,無錯誤!" << endl;
    }
    else if (state == ios_base::failbit)
    {
        cout << "輸入數據類型錯誤,非致命錯誤,可清除輸入緩衝區挽回!" << endl;
    }
    system("pause");

    return 0;
}

咱們定義要輸入的變量是整型,但若是輸入了英文字母或者漢字,那就會發生錯誤,cin裏有個方法能檢測這個錯誤,就是rdstate()。

當rdstate()返回0(即ios::goodbit)時表示無錯誤,能夠繼續輸入或者操做,若返回2則發生非致命錯誤即ios::failbit,則不能繼續輸入或操做。而clear()則能夠控制咱們此時cin裏對這個問題的一個標識。

語法:cin.clear(標識符)

標識符號爲:

  • goodbit:無錯誤。
  • Eofbit:已到達文件尾。
  • failbit:非致命的輸入/輸出錯誤,可挽回。
  • badbit:致命的輸入/輸出錯誤,沒法挽回。

若在輸入輸出類裏,須要加ios::標識符號。

sync()

經過clear(),咱們能確認它的內部標識符,若是輸入錯誤則能從新輸入。結合真正的清空數據流方法sync(),請看下例:

#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    int a;
    while (true)
    {
        cin >> a;
        if (!cin)  //條件可改寫爲cin.fail()
        {
            cout << "輸入類型錯誤,請從新輸入!" << endl;
            cin.clear(); //復爲標誌,將cin中的全部標誌設置爲有效狀態
            cin.sync(); //清空流
        }
        else
        {
            cout << a << endl;
            break;
        }
    }
    system("pause");

    return 0;
}

上面的cin默認值爲非0,當輸入爲非整形時,它的狀態標識符改成fail(即:0),再用clear()讓錯誤標識改回爲非0,能夠繼續輸入,再清空流數據繼續輸入。若是沒有了clear(),則會進入死循環,其過程爲咱們輸入了英文字母,它的狀態標識便爲fail,當運行到條件判斷時,便老是回到錯誤的條件表示裏,而且再也沒有辦法輸入,由於錯誤的表示關閉了cin,因此會進入死循環。

能夠分別註釋掉clear()和sync()進行驗證。

相關文章
相關標籤/搜索