清除鍵盤緩沖區(qū)_第1頁
清除鍵盤緩沖區(qū)_第2頁
清除鍵盤緩沖區(qū)_第3頁
清除鍵盤緩沖區(qū)_第4頁
清除鍵盤緩沖區(qū)_第5頁
已閱讀5頁,還剩2頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、今天發(fā)現(xiàn)了清空緩沖區(qū)的問題,上網(wǎng)搜尋,發(fā)現(xiàn)如下方法。輸入輸出緩沖區(qū)的概念(C+用的多一些)我想以一個(gè)例子說明,比如我想把一篇文章以字符序列的方式輸出到計(jì)算機(jī)顯示器屏幕 上,那么我的程序內(nèi)存作為數(shù)據(jù)源而顯示器驅(qū)動(dòng)程序作為數(shù)據(jù)目標(biāo),如果數(shù)據(jù)源直接對(duì)數(shù)據(jù) 目標(biāo)發(fā)送數(shù)據(jù)的話。數(shù)據(jù)目標(biāo)獲得第一個(gè)字符,便將它顯示。然后從端口讀取下一個(gè)字符, 可是這時(shí)就不能保證數(shù)據(jù)源向端口發(fā)送的恰好是第二個(gè)字符(也許是第三個(gè),而第二個(gè)已經(jīng) 在數(shù)據(jù)目標(biāo)顯示時(shí)發(fā)送過了)。這樣的話就不能保證輸出的數(shù)據(jù)能完整的被數(shù)據(jù)目標(biāo)所接受 并處理。為了解決這個(gè)問題,我們需要在數(shù)據(jù)源與數(shù)據(jù)目標(biāo)中間放置一個(gè)保存完整數(shù)據(jù)內(nèi)容的 區(qū)域,那就是“緩沖區(qū)

2、”。這樣的話,數(shù)據(jù)源可以不考慮數(shù)據(jù)目標(biāo)正在處理哪部分?jǐn)?shù)據(jù), 只要把數(shù)據(jù)輸出到緩沖區(qū)就可以了,數(shù)據(jù)目標(biāo)也可以不考慮數(shù)據(jù)源的發(fā)送頻率,只是從緩沖 區(qū)中依次取出下一個(gè)數(shù)據(jù)。從而保證了數(shù)據(jù)發(fā)送的完整性,同時(shí)也提高了程序的效率。當(dāng)然getch(),getche()沒有用到緩沖區(qū)。幾個(gè)函數(shù)的區(qū)別首先不要忘了,要用getch()必須引入頭文件conio.h,以前學(xué)C語言的時(shí)候,我們總喜 歡用在程序的末尾加上它,利用它來實(shí)現(xiàn)程序運(yùn)行完了暫停不退出的效果。如果不加這句話, 在TC2.0的環(huán)境中我們用Ctrl+F9編譯并運(yùn)行后,程序一運(yùn)行完了就退回到TC環(huán)境中,我 們根本來不及看到結(jié)果,這時(shí)要看結(jié)果,我們就要按A

3、lt+F5回到DOS環(huán)境中去看結(jié)果,這 很麻煩。而如果在程序的結(jié)尾加上一行g(shù)etch();語句,我們就可以省掉會(huì)DOS看結(jié)果這個(gè)步 驟,因?yàn)槌绦蜻\(yùn)行完了并不退出,而是在程序最后把屏幕停住了,按任意鍵才退回到TC環(huán) 境中去。那我們來看看getch()到底起的什么作用,getch()實(shí)際是一個(gè)輸入命令,作用是從鍵盤接 收一個(gè)字符,而且并不把這個(gè)字符顯示出來,就是說,你按了一個(gè)鍵后它并不在屏幕上顯示 你按的什么,而繼續(xù)運(yùn)行后面的代碼,所以我們?cè)贑+中可以用它來實(shí)現(xiàn)“按任意鍵繼續(xù)” 的效果,即程序中遇到getch();這行語句,它就會(huì)把程序暫停下來,等你按任意鍵,它接收 了這個(gè)字符鍵后再繼續(xù)執(zhí)行后面的

4、代碼。你也許會(huì)問,為什么我們?cè)贑+中就沒有在程序的末尾加上getch(),解釋是,軟件總 是不斷更新的,不好的地方當(dāng)然要進(jìn)行改正,getch()加在程序末尾,它又不賦值給任何變量, 所以它在這個(gè)地方完全是垃圾代碼,與程序無關(guān)。C+中考慮到這一點(diǎn),于是在每次程序運(yùn) 行完了并不退出,而是自動(dòng)把屏幕停下來,并顯示“press any key.”叫你按任意鍵退出, 這就好比C+在它的環(huán)境中運(yùn)行程序,在程序的末尾自動(dòng)加上了一行g(shù)etch();語句,并且在 這行語句前還添加了一行輸出語句coutpress any key.;來提示你程序結(jié)束了,按任意鍵 繼續(xù)。實(shí)際上我們編譯好的程序在程序結(jié)束了本身是不會(huì)停

5、下來的,我們可以在編譯產(chǎn)生的 Debug目錄中找到這個(gè)編譯好的應(yīng)用程序(擴(kuò)展名exe),在文件夾中雙擊運(yùn)行它,你會(huì)發(fā) 現(xiàn)屏幕閃了一下MS-DOS窗口就關(guān)閉了,因?yàn)槌绦蜻\(yùn)行完就自動(dòng)退出了,回到了 windows 環(huán)境,當(dāng)然,如果我們?cè)贒OS環(huán)境中運(yùn)行這個(gè)程序,我們就可以直接在看到DOS屏幕上看 到程序運(yùn)行結(jié)果,因?yàn)槌绦蜻\(yùn)行完后并不清屏。但是,visual 2003有返回到了 tc那 樣的情況,你必需要有個(gè)getch()才行。getche()和 getch()很相似,它也需要引入頭文件conio.h,那它們之間的區(qū)別又在哪里呢? 不同之處就在于getch()無返回顯示,getche()有返回顯示。

6、就這么一點(diǎn)看看下面的例子: #include#includevoid main()char ch;for(int i=0;i5;i+)ch=getch();printf(%c,ch);首先這是個(gè)連續(xù)5次的循環(huán)來實(shí)現(xiàn)5次停頓,等待我們輸入,我們編譯并運(yùn)行這個(gè)程序, 假設(shè)我們分別輸入abcde,屏幕上顯示的結(jié)果是abcde,這個(gè)abcde并不是在ch=getch();中輸 出的,我們把printf(%c”,ch);這行語句去掉,就會(huì)發(fā)現(xiàn)我們按5次任意鍵程序就結(jié)束了,但 屏幕上什么都沒有顯示。然后我們?cè)诎汛a中的getch()換成getche()看看有什么不同,我們還是分別輸入abcde, 這時(shí)屏幕

7、上顯示的結(jié)果是aabbccddee,我們把printf(%c”,ch);這行語句再去掉看看,顯示的 結(jié)果就是abcde 了,說明程序在執(zhí)行ch=getche();這條語句的時(shí)候就把我們輸入的鍵返回顯 示在屏幕上,有無回顯就是它們的唯一區(qū)別。有人會(huì)說,既然是C的函數(shù)庫中的,那么就應(yīng)該淘汰了,我們還研究它,還用它干嘛? 但是我發(fā)現(xiàn)還是有用著它的地方,否則我也不會(huì)在這里說這么多來耽誤大家的時(shí)間。我就舉 個(gè)例子吧,程序如下:#include#includevoid main()char ch=*;while(ch=*)printf(n按*繼續(xù)循環(huán),按其他鍵退出!”);ch=getch();printf

8、(n 退出程序!”);我們可以在這個(gè)循環(huán)體中添加我們想要的功能,程序中按*繼續(xù)循環(huán),其他任意鍵退出, 而且利用getch()無回顯的特性,我們不管按什么,都不會(huì)在屏幕上留下痕跡,使我們的界 面達(dá)到美觀效果,如果還有更好的辦法實(shí)現(xiàn)這個(gè)功能。例子:void main()char c, ch;c=getch();/*從鍵盤上讀入一個(gè)字符不回顯送給字符變量c*/putchar(c); /*輸出該字符*/ch=getche();/*從鍵盤上帶回顯的讀入一個(gè)字符送給字符變量ch*/putchar(ch);printf(nn);值得注意的是前面兩個(gè)函數(shù)都是從鍵盤讀入數(shù)據(jù)!還有g(shù)etchar是很值得研究的:g

9、etchar()是stdio.h中的庫函數(shù),它的作用是從stdin流中 讀入一個(gè)字符,也就是說,如果stdin有數(shù)據(jù)的話不用輸入它就可以直接讀取了。而getch() 和getche()是conio.h中的庫函數(shù),它的作用是從鍵盤接收字符。getchar帶有顯示。與前面兩個(gè)函數(shù)的區(qū)別在于:getchar()函數(shù)等待輸入直到按回車才結(jié)束(前提是緩沖 區(qū)沒有數(shù)據(jù)),回車前的所有輸入字符都會(huì)逐個(gè)顯示在屏幕上。但只有第一個(gè)字符作為函數(shù) 的返回值。#include#includevoid main()char c;c=getchar();/*從鍵盤讀入字符直到回車結(jié)束*/getchar()在這里它只返回你

10、輸入字符串的第一個(gè)字符,并把返回值賦值給cputchar(c);/*顯示輸入的第一個(gè)字符*/printf(nn);例四:呵呵,這個(gè)程序你運(yùn)行一下,相信你又會(huì)有疑問了。這個(gè)就是從緩沖區(qū)中讀取了例子。 第一次getchar()時(shí),確實(shí)需要人工的輸入,但是如果你輸了多個(gè)字符,以后的getchar()再執(zhí) 行時(shí)就會(huì)直接從緩沖區(qū)中讀取了。#include#includevoid main()char c;while (c=getchar()!=n)/*每個(gè) getchar()依次讀入一個(gè)字符*/printf(%c,c); /* 按照原樣輸出 */printf(nn);程序運(yùn)行時(shí),首先停下來,等你輸入一串

11、字符串,輸入完畢后,它把你輸入的整個(gè)字符 串都輸出來了,咦,你不是說getchar()只返回第一個(gè)字符么,這里怎么? 因?yàn)槲覀冚斎氲淖址⒉皇侨×说谝粋€(gè)字符就把剩下的字符串丟掉了,它還在我們的內(nèi)存 中,就好比,開閘放水,我們把水放到閘里去以后,開一次閘就放掉一點(diǎn),開一次就放掉一 點(diǎn),直到放光了為止,這里開閘動(dòng)作就相當(dāng)于調(diào)用一次getchar()。我們輸入的字符串也是這 么一回事,首先我們輸入的字符串是放在內(nèi)存的緩沖區(qū)中的,我們調(diào)用一次getchar()就把緩 沖區(qū)中里出口最近的一個(gè)字符輸出,也就是最前面的一個(gè)字符輸出,輸出后,就把它釋放掉 了,但后面還有字符串,所以我們就用循環(huán)把最前面的一個(gè)

12、字符一個(gè)個(gè)的在內(nèi)存中釋放掉, 直到不滿足循環(huán)條件退出為止。例子中循環(huán)條件里的n實(shí)際上就是你輸入字符串后的回車符,所以意思就是說,直到遇到 回車符才結(jié)束循環(huán),而getchar()函數(shù)就是等待輸入(或緩沖區(qū)中的數(shù)據(jù))直到按回車才結(jié)束, 所以實(shí)現(xiàn)了整個(gè)字符串的輸出。當(dāng)然,我們也可以把循環(huán)條件改一下,比如while (c=getchar()!=a),什么意思呢,意思就是遇到字符a 就停止循環(huán),當(dāng)然意思是如果你輸入 “12345a213123n”那么只會(huì)輸出到a,結(jié)果是12345a。再次注意:用getchar()它是從“流”中間去讀取,所以第一個(gè)getchar()接受的是剛剛中斷的 流隊(duì)列中即將出列的第

13、一個(gè)字符(不限于回車符,上面舉過例子了),如果流隊(duì)列不為空, 執(zhí)行g(shù)etchar()就繼續(xù)放水,直到把回車符也放空為止,空了之后再在執(zhí)行g(shù)etchar()就停下等 待你的輸入了;我們用getch()為什么每次都是等待用戶的輸入呢?因?yàn)間etch()是從鍵盤接 收,即時(shí)的接收,并不是從stdin流中去讀取數(shù)據(jù)。補(bǔ)充:按鍵盤上的回車產(chǎn)生了 2個(gè)字符:回車符(r)和換行符(n)。回車符r(CR:carriage return:倒車)使光標(biāo)回到這行的首部,換行符(n)(new line)然后再換行。所以當(dāng)輸入字符w,并按下回車鍵以后。首先得到回車符。那個(gè)getchar函數(shù)結(jié)束了。但 是還存在一個(gè)換行符

14、。所以如果用getchar()來做判斷的時(shí)候。最好再寫一次getchar()清除緩 沖區(qū)的n.如何清空輸入緩沖區(qū)的內(nèi)容?如果我想讓getchar()每次都能夠等待用戶輸入的話就要清空緩沖區(qū),下面就介紹方法 (不同平臺(tái))C標(biāo)準(zhǔn)規(guī)定fflush()函數(shù)是用來刷新輸出(stdout)緩存的。對(duì)于輸入(stdin),它是 沒有定義的。但是有些編譯器也定義了 fflush( stdin )的實(shí)現(xiàn),比如微軟的VC。其它編譯器 是否也定義了 fflush( stdin )的實(shí)現(xiàn)應(yīng)當(dāng)查找它的手冊(cè)。GCC編譯器沒有定義它的實(shí)現(xiàn),所 以不能使用fflush( stdin )來刷新輸入緩存。對(duì)于沒有定義fflush

15、( stdin )的編譯器,可以使用fgets()函數(shù)來代替它(比用getchar()、scanf()等函數(shù)通用性好)。可以這樣忽略輸入流中留下的回車等其它輸入,從而使 下一次的輸入總保持一個(gè)“干凈”的狀態(tài)。(這個(gè)是任何平臺(tái)下都可以的)/ .char sbuf1024;/ .fgets( sbuf, 1024, stdin );/ .在windows的vc下面就可以這樣了:for(int i=0;i10;+i)char ch=getchar();fflush(stdin); /每次都會(huì)有等待狀態(tài)了總結(jié)主要看getch(),getche()的是否顯示,getchar()是讀取流,而且和前面兩個(gè)函

16、數(shù)不是一 個(gè)庫。掌握清空緩沖區(qū)的方法。二。fflush( FILE * pStream )清空一個(gè)流pStream可以是 stdinstdout stderr stdprn stdauxflushall() 清空所有流需要包含 stdio.h二 。四。int n;int ret;do printf( Input an integer:);ret = scanf( %d, &n );while ( getchar() != n ); /* Clear the input buffer */ while ( ret != 1 );/*執(zhí)行這一段函數(shù)*/當(dāng)用戶如果輸入一個(gè)數(shù)字的時(shí)候,那么這個(gè)時(shí)候n定

17、義的是一個(gè)整型就將這個(gè)整型接收 ret = scanf( %d, &n );的意思不等于 ret=n;而是當(dāng)n接收到一個(gè)整型值時(shí)候ret=1;while ( ret != 1 );跳出循環(huán)如果當(dāng)用戶輸入一個(gè)字符類型的數(shù)據(jù),那么這個(gè)時(shí)候n已定義為一個(gè)整型就無法接收了 所以n沒有接收到值此時(shí)候ret=0;而getchar正是來接受字符的,當(dāng)用戶輸入了回車(n)后接收完畢跳出while ( getchar() != n);注意這里的while順環(huán)體為空語句這個(gè)時(shí)候while ( ret != 1 );(因?yàn)閞et=0,條件為真繼續(xù)執(zhí)行該循環(huán))所以說如果你輸入了一個(gè)非int類型那么接下來的又會(huì)prin

18、tf( Input an integer: );ret = scanf( %d, &n );(直到輸入為int類型止)五。C+ 雖然不可以用fflush(stdin),但是我們可以自己寫代碼來清空輸入緩沖區(qū)。只需要在scanf函 數(shù)后面加上幾句簡(jiǎn)單的代碼就可以了。/* C版本*/#include int main( void )int i, c;for (;) fputs(Please input an integer: , stdout);if ( scanf(%d”, &i) != EOF ) /* 如果用戶輸入的不是 EOF */* while循環(huán)會(huì)把輸入緩沖中的殘留字符清空*/*可以根據(jù)需要把它改成宏或者內(nèi)聯(lián)函數(shù)*/*注:C99中也定義了內(nèi)聯(lián)函數(shù),gcc3.2支持*/while ( (c=getchar() != n & c != EOF ) ; /* end of while */printf(%dn, i);return 0;/* C+ 版本 */#include #include / 為 了使用 numeric_limitsusing std:cout;usin

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論