电竞比分网-中国电竞赛事及体育赛事平台

分享

cin深入分析(上) - cin輸入操作處理(轉(zhuǎn))_斯萊克威

 xiai_fei 2009-09-19
cin深入分析(上) - cin輸入操作處理

很多初學(xué)者都認(rèn)為cin函數(shù)是一個很簡單的函數(shù),其實(shí)不然!cin函數(shù)有很多需要了解的知識(比如:cin的返回值是什么,cin提供了哪些成員函數(shù)且分別是什么作用,如cin.clear(), cin.ignore(), cin.fail(), cin.good()等等),如果沒有很好的掌握,在使用的時候很可能會出問題卻不知其原因!而且很多人也確確實(shí)實(shí)遇到過不少問題,以下是幾個簡單的例子:

程序1:

#include <iostream>

using namespace std;

int main()

{

int m, n;

cin>>m;

cin>>n;

return 0;

}

測試情況:

如果用戶每次都輸入兩個合法的數(shù),程序不會出問題!

但是如果用戶第一次輸入時給一個非法的輸入,比如說輸入一個字符'a',你會發(fā)現(xiàn)程序不

會再執(zhí)行第二條輸入語句。似乎有點(diǎn)奇怪!!



程序2:

#include <iostream>

using namespace std;

int main()

{

char str[8];

cin.getline(str, 5);

cout<<str<<endl;

cin.getline(str, 5);

cout<<str<<endl;

return 0;

}

程序的功能很簡單,就是輸入一個字符串再輸出,再次輸入一個字符串輸出。程序執(zhí)行情況:

測試一:

abcd (回車)

abcd (輸出)

efgh (回車)

efgh (輸出)

當(dāng)用戶第一次輸入的字符串字符數(shù)小于4時,程序執(zhí)行正常!



測試二:

abcdefgh (回車)

abcd (輸出)

(輸出-換行)

當(dāng)用戶第一次輸入的字符數(shù)字符數(shù)大于4時,第一個字符串接受輸入的前四個字符,而第二次的輸入操作沒有執(zhí)行,第二個字符串輸出為空。似乎也很奇怪?。?!

其實(shí)在很多時候都會遇到諸如此類的問題,如果不熟悉程序輸入的原理和cin等一些函數(shù)的原理就不知道怎么解決!我在這里做一個簡單的介紹,也許介紹得不是很準(zhǔn)確和全面,或者存在一些誤解,請大家包涵!


輸入操作的原理

與前一節(jié)中提到的scanf函數(shù)一樣,程序的輸入都建有一個緩沖區(qū),即輸入緩沖區(qū)。一次輸入過程是這樣的,當(dāng)一次鍵盤輸入結(jié)束時會將輸入的數(shù)據(jù)存入輸入緩沖區(qū),而cin函數(shù)直接從輸入緩沖區(qū)中取數(shù)據(jù)。正因?yàn)閏in函數(shù)是直接從緩沖區(qū)取數(shù)據(jù)的,所以有時候當(dāng)緩沖區(qū)中有殘留數(shù)據(jù)時,cin函數(shù)會直接取得這些殘留數(shù)據(jù)而不會請求鍵盤輸入,這就是例子中為什么會出現(xiàn)輸入語句失效的原因!


cin的一些輸入函數(shù)和操作符

cin is a extern istream object。提供了很多可用的成員函數(shù)和重載的操作符,如:cin<<, cin.get(), cin.getline()等。下面我們來了解一下這幾個函數(shù):



一. cin<<

該操作符是根據(jù)后面變量的類型讀取數(shù)據(jù)。

輸入結(jié)束條件:遇到Enter、Space、Tab鍵。(這個很重要!)

對結(jié)束符的處理:丟棄緩沖區(qū)中使得輸入結(jié)束的結(jié)束符(Enter、Space、Tab)



讀字符的情況:

程序3:

#include <iostream>

using namespace std;

int main()

{

char c1, c2;

cin>>c1;

cin>>c2;

cout<<c1<<" "<<c2<<endl;

return 0;

}

測試一輸入:

a[Enter]

b[Enter]

輸出:

a b



測試二輸入:

a b[Enter]

輸出:

a b





讀字符串的情況:

程序4:

#include <iostream>

using namespace std;

int main()

{

char str1[10], str2[10];

cin>>str1;

cin>>str2;

cout<<str1<<endl;

cout<<str2<<endl;

return 0;

}

測試一輸入:

abcd[Enter]

efgh[Enter]

輸出:

abcd

efgh

【分析】輸入遇到回車符結(jié)束,很正常。



測試二輸入:

abcd efgh

輸出:

abcd

efgh

【分析】第一次讀取字符串時遇到空格則停止了,將abcd讀入str1,并舍棄了空格,將后面的字符串給了第二個字符串。這證明了cin讀入數(shù)據(jù)遇到空格結(jié)束;并且丟棄空格符;緩沖區(qū)有殘留數(shù)據(jù)室,讀入操作直接從緩沖區(qū)中取數(shù)據(jù)。





二.cin.get()

該函數(shù)有三種格式:無參,一參數(shù),二參數(shù)

即cin.get(),cin.get(char ch),cin.get(array_name, Arsize)



讀取字符的情況:

輸入結(jié)束條件:Enter鍵

對結(jié)束符處理:不丟棄緩沖區(qū)中的Enter

cin.get()與cin.get(char ch)用于讀取字符,他們的使用是相似的,

即:ch=cin.get()與cin.get(ch)是等價的。

程序5:

#include <iostream>

using namespace std;

int main()

{

char c1, c2;

cin.get(c1);

cin.get(c2);

cout<<c1<<" "<<c2<<endl;//打印兩個字符

cout<<(int)c1<<" "<<(int)c2<<endl;//打印這兩個字符的ASCII值

return 0;

}

測試一輸入:

a[Enter]

輸出:

a



97 10

【分析】會發(fā)現(xiàn)只執(zhí)行了一次從鍵盤輸入,顯然第一個字符變量取的'a',第二個變量取的是Enter(ASCII值為10),這是因?yàn)樵摵瘮?shù)不丟棄上次輸入結(jié)束時的Enter字符,所以第一次輸入結(jié)束時緩沖區(qū)中殘留的是上次輸入結(jié)束時的Enter字符!



測試二輸入:

a b[Enter]

輸出:

a

97 32

【分析】顯然第一個字符變量取的'a',第二個變量取的是Space(ASCII值為32)。原因同上,沒有丟棄Space字符。



讀取字符串的情況:

cin.get(array_name, Arsize)是用來讀取字符串的,可以接受空格字符,遇到Enter結(jié)束輸入,按照長度(Arsize)讀取字符,會丟棄最后的Enter字符。

程序6:

#include <iostream>

using namespace std;

int main ()

{

char a[20];

cin.get(a, 10);

cout<<a<<endl;

return 0;

}

測試一輸入:

abc def[Enter]

輸出:

abc def

【分析】說明該函數(shù)輸入字符串時可以接受空格。



測試二輸入:

1234567890[Enter]

輸出:

123456789

【分析】輸入超長,則按需要的長度取數(shù)據(jù)。



程序7:

#include <iostream>

using namespace std;

int main ()

{

char ch, a[20];

cin.get(a, 5);

cin>>ch;

cout<<a<<endl;

cout<<(int)ch<<endl;

return 0;

}

測試一輸入:

12345[Enter]

輸出:

1234

53

【分析】第一次輸入超長,字符串按長度取了"1234",而'5'仍殘留在緩沖區(qū)中,所以第二次輸入字符沒有從鍵盤讀入,而是直接取了'5',所以打印的ASCII值是53('5'的ASCII值)。



測試二輸入:

1234[Enter]

a[Enter]

輸出:

1234

97

【分析】第二次輸入有效,說明該函數(shù)把第一次輸入后的Enter丟棄了!





三.cin.getline()

cin.getline()與cin.get(array_name, Arsize)的讀取方式差不多,以Enter結(jié)束,可以接受空格字符。按照長度(Arsize)讀取字符,會丟棄最后的Enter字符。

但是這兩個函數(shù)是有區(qū)別的:

cin.get(array_name, Arsize)當(dāng)輸入的字符串超長時,不會引起cin函數(shù)的錯誤,后面的cin操作會繼續(xù)執(zhí)行,只是直接從緩沖區(qū)中取數(shù)據(jù)。但是cin.getline()當(dāng)輸入超長時,會引起cin函數(shù)的錯誤,后面的cin操作將不再執(zhí)行。(具體原因?qū)⒃谙乱徊糠?cin的錯誤處理"中詳細(xì)介紹)

程序8:

#include <iostream>

using namespace std;

int main ()

{

char ch, a[20];

cin.getline(a, 5);

cin>>ch;

cout<<a<<endl;

cout<<(int)ch<<endl;

return 0;

}

測試輸入:

12345[Enter]

輸出:

1234

-52

【分析】與cin.get(array_name, Arsize)的例程比較會發(fā)現(xiàn),這里的ch并沒有讀取緩沖區(qū)中的5,而是返回了-52,這里其實(shí)cin>>ch語句沒有執(zhí)行,是因?yàn)閏in出錯了!

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多