在C中,輸入輸出用scanf和printf,在輸入數據的同時還需說明數據的類型,若是輸入數據較多,那就很麻煩,而C++中也有類似的東西cin和cout,它們來自C++的一個名叫」 iostream」的類庫。ios
iostream是由istream(輸入流)和ostream(輸出流)派生。因此在iostream中就有了輸入和輸出的相關對象:markdown
cout與cerr的區別:cout的輸出能夠重定向到一個文件中,而cerr必須輸出在顯示器上。學習
暫時先介紹這些,如下主要介紹cin中get()、getline()、clear()、sync()的用法。ui
首先看看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中的流數據中刪除一個字母,起了一個刪除做用。
對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()的做用,第一次看到這東西,不少人覺得就是清空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(標識符)
標識符號爲:
若在輸入輸出類裏,須要加ios::標識符號。
經過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()進行驗證。