C++字符串輸入緩沖區(qū)機(jī)制詳解
一、緩沖定義
1.緩沖定義
緩沖是在兩種不同速度設(shè)備之間傳輸信息時(shí)平滑傳輸過程的常用手段。
2.為什么引入緩沖區(qū)
操作系統(tǒng)這門課有明確的說明緩沖的作用,是為了解決高速設(shè)備和低速設(shè)備之間速度不匹配的問題,直接舉個(gè)書上的CPU和打印機(jī)的例子:
首先我們要用打印機(jī)打印一篇文章肯定要經(jīng)過CPU處理然后給到打印機(jī)打印文章,但是CPU處理1000個(gè)字節(jié)的文字一眨眼的事情,但是打印機(jī)可能需要若干秒,總不可能讓CPU處理一個(gè)數(shù)據(jù)給打印機(jī)一個(gè)數(shù)據(jù)這樣子等著運(yùn)行,這就引入了緩沖區(qū),CPU處理完數(shù)據(jù)存入緩沖區(qū),打印機(jī)直接從緩沖區(qū)提取已經(jīng)處理好的數(shù)據(jù),這樣子就解決了高速設(shè)備(CPU)和低速設(shè)備(打印機(jī))處理速度不匹配的問題。
二、scanf,cin輸入緩沖區(qū)
1.scanf和cin的緩沖類型
scanf和cin的緩沖類型為行緩沖,行緩沖的的特點(diǎn)是在輸入數(shù)據(jù)只要沒有碰到換行符(回車)就將數(shù)據(jù)存入輸入緩沖區(qū),當(dāng)碰到換行符之后就將緩沖區(qū)中的數(shù)據(jù)取出使用。
2.scanf和cin的緩沖機(jī)制
scanf和cin輸入數(shù)據(jù)緩沖機(jī)制基本一致,在讀入一個(gè)數(shù)據(jù)時(shí)直到回車之前他都會(huì)存儲(chǔ)在輸入緩沖區(qū)中,直到碰到回車才會(huì)將數(shù)據(jù)從輸入緩沖區(qū)中取出供變量使用,但是緩沖區(qū)中的換行符會(huì)被留在輸入緩沖區(qū)中。
3.cin.getline和cin.get
cin.get讀取字符串直到讀取到回車為止,但是也會(huì)將回車留在緩沖區(qū)。
cin.getline讀取字符串直到讀取到回車為止,但是不會(huì)講回車留在緩沖區(qū)。
4.scanf和cin輸入
①cin和scanf讀取一個(gè)字符的區(qū)別
char c; cin>>c;//cin讀取字符的時(shí)候不會(huì)讀入空格、回車以及制表符,如果緩沖區(qū)開頭是換行符或者制表符會(huì)被忽略并清除 scanf("%c",&c);//scanf讀取字符的時(shí)候不會(huì)管你是什么字符直接讀進(jìn)來
②cin和scanf在讀取緩沖區(qū)中的數(shù)字、字符串、浮點(diǎn)型的時(shí)候不會(huì)將開頭的空格、換行符或者制表符當(dāng)作數(shù)據(jù)讀入,如果碰到了他們會(huì)將它們忽略并清除。需要注意cin.get和cin.getline不會(huì)將開頭的空格、換行符或者制表符忽略并刪除。
5.可能遇到的問題
①在用cin或者scanf讀取一個(gè)字符串之后scanf再讀取一個(gè)字符,發(fā)現(xiàn)讀取的字符沒辦法輸入而且輸出了一個(gè)回車??慈缦麓a:
char name[20]; char c; cin>>name; cout<<name<<endl; scanf("%c",&c); cout<<"---"<<int(c)<<endl;
結(jié)果如下截圖:
當(dāng)我們輸入name為123的時(shí)候程序就結(jié)束了輸出c的值為10,在ASCII碼編碼中10對(duì)應(yīng)的是換行符,為什么會(huì)出現(xiàn)上述這種情況呢?因?yàn)閏in輸入完之后將回車保留在了緩沖區(qū)中,而scanf("%c",&c)輸入字符并不會(huì)判斷是空格還是回車,直接將緩沖區(qū)中的回車拿了出來給了字符變量c。
②用cin.getline輸入字符串之后再用scanf讀取一個(gè)字符就和上面不一樣了??慈缦麓a:
char name[20]; char c; cin.getline(name,20); cout<<name<<endl; scanf("%c",&c); cout<<"---"<<int(c)<<endl;
結(jié)果如下截圖:
結(jié)果不同的原因是因?yàn)閟canf,cin,cin.get在行緩沖取出數(shù)據(jù)之后會(huì)將換行符留在緩沖區(qū)中,然后再用scanf讀入一個(gè)字符發(fā)現(xiàn)緩沖區(qū)并不為空就從緩沖區(qū)中將數(shù)據(jù)拿出來,而cin.getline會(huì)將緩沖區(qū)中的換行符也清除,所以不會(huì)有①這種情況出現(xiàn)。
③讀入一個(gè)字符串之后后面的cin.get()一直無法讀取數(shù)據(jù),看如下代碼:
char name[20]; cin.get(name,20); cout<<"--"<<name<<endl; cin.get(name,20); cout<<"--"<<name<<endl; cin.get(name,20); cout<<"--"<<name<<endl; cin.get(name,20); cout<<"--"<<name<<endl; cin.get(name,20); cout<<"--"<<name<<endl;
結(jié)果如下截圖:
可以看到用第一個(gè)cin.get輸入了數(shù)據(jù)之后后面的cin.get都無效了,這是因?yàn)閏in.get從緩沖區(qū)中讀取到換行符就結(jié)束并將換行符保留在緩沖區(qū)中,接下來的cin.get一直在緩沖區(qū)中碰到換行符就一直沒有實(shí)際數(shù)據(jù)輸入。
④整形和字符串混合輸入
當(dāng)先輸入一個(gè)整形再用cin.getline輸入字符串會(huì)發(fā)現(xiàn)沒有經(jīng)歷輸入字符串的過程,測(cè)試如下代碼:
char name[20]; int a; cin>>a; cout<<a<<endl; cin.getline(name,20); cout<<"---"<<name<<endl; cout<<"end"<<endl;
結(jié)果如下:
根據(jù)上面的緩沖原理比較容易理解,cin輸入一個(gè)整形后會(huì)在緩沖區(qū)中留下一個(gè)換行符,因?yàn)榫彌_區(qū)中有換行符剩余,cin.getline從緩沖區(qū)中取出數(shù)據(jù)發(fā)現(xiàn)正好是換行符,那么就默認(rèn)字符串輸入完了,并將換行符從緩沖區(qū)中去掉,所以造成了上面的局面。
清除緩沖區(qū)
上面講的問題基本上都是因?yàn)榫彌_區(qū)中剩余的數(shù)據(jù)造成的,那么只需要有方法清除緩沖區(qū)就行了,可以用getchar(),cin.get()讀取緩沖區(qū)中多的換行符。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C++實(shí)現(xiàn)數(shù)據(jù)文件存儲(chǔ)與加載
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)數(shù)據(jù)文件存儲(chǔ)與加載,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06Clion-MinGW編譯后的exe文件添加ico圖標(biāo)的操作方法
這篇文章主要介紹了Clion-MinGW編譯后的exe文件添加ico圖標(biāo)的操作方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07C++之構(gòu)造函數(shù)默認(rèn)值設(shè)置方式
這篇文章主要介紹了C++之構(gòu)造函數(shù)默認(rèn)值設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08C++構(gòu)造函數(shù)+復(fù)制構(gòu)造函數(shù)+重載等號(hào)運(yùn)算符調(diào)用
這篇文章主要介紹了C++構(gòu)造函數(shù)+復(fù)制構(gòu)造函數(shù)+重載等號(hào)運(yùn)算符調(diào)用,文章敘述詳細(xì),具有一定的的參考價(jià)值,需要的小伙伴可以參考一下2022-03-03C語言編程技巧 關(guān)于const和#define的區(qū)別心得
盡量用const和inline而不用#define 這個(gè)條款最好稱為:“盡量用編譯器而不用預(yù)處理”,因?yàn)?define經(jīng)常被認(rèn)為好象不是語言本身的一部分。這是問題之一。再看下面的語句:2013-02-02簡(jiǎn)單介紹C++編程中派生類的析構(gòu)函數(shù)
這篇文章主要介紹了C++編程中派生類的析構(gòu)函數(shù),析構(gòu)函數(shù)平時(shí)一般使用較少,需要的朋友可以參考下2015-09-09詳談全排列next_permutation() 函數(shù)的用法(推薦)
下面小編就為大家?guī)硪黄斦勅帕衝ext_permutation() 函數(shù)的用法(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03c語言實(shí)現(xiàn)把文件中數(shù)據(jù)讀取并存到數(shù)組中
下面小編就為大家?guī)硪黄猚語言實(shí)現(xiàn)把文件中數(shù)據(jù)讀取并存到數(shù)組中。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-12-12