溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C語言中的getchar()該怎么使用

發(fā)布時間:2022-01-17 09:08:07 來源:億速云 閱讀:127 作者:柒染 欄目:開發(fā)技術(shù)

小編今天帶大家了解C語言中的getchar()該怎么使用,文中知識點介紹的非常詳細。覺得有幫助的朋友可以跟著小編一起瀏覽文章的內(nèi)容,希望能夠幫助更多想解決這個問題的朋友找到問題的答案,下面跟著小編一起深入學(xué)習(xí)“C語言中的getchar()該怎么使用”的知識吧。

前言

近期我在重新學(xué)習(xí)C語言時候,我發(fā)現(xiàn)了一個嚴重的問題,getchar我居然不會用了....也不是說不會用,我發(fā)現(xiàn)了一個非常讓我困惑想不明白的問題。可能我在第一次接觸C語言時候,就沒有把這個概念弄清楚吧,以至于現(xiàn)在會不明白。

getchar困惑的點

C語言中的getchar()該怎么使用

我利用getchar函數(shù)輸入了一串字符ABCD,然后把這串字符給到ch,然后緊接著我打印這個ch,然后我得到了一個字符A,看到這里大家沒有感覺有什么問題對吧,當然沒有問題,因為getchar只會讀一個字符,自然就只讀到了A,然后打印時候也自然而然就只打印了這個A出來。

好的我們接著往下看

C語言中的getchar()該怎么使用

看到這個我不知道大家有沒有想到一個問題,反正我當時就是因為這個問題所困惑很久的。

首先通過第一個例子,我們知道了,getchar是只會讀取一個字符

可是這個例子呢,我輸入了一串字符ABCDE,按理說他也只是讀取到一個字符,那就是這串字符中的第一個字符A,然后讀取到了之后把它給了變量ch, 然后來判斷這個ch等不等于EOF。

EOF是文件結(jié)束標志,在鍵盤上也就是ctrl+z 大家可以自己打印一下然后對照ASCII碼看一下

很顯然,當前這個里面根本就沒有ctrl+z,所以條件為真,然后執(zhí)行打印語句。

根據(jù)上面我們那段分析,然后應(yīng)該打印一個字符A對嗎,疑惑的事情發(fā)生了,它打印了ABCDE?。?!是的,完完整整打印出來了。

可能大家經(jīng)常見到這個類似程序,然后習(xí)以為常了,都覺得是應(yīng)該完完整整打印出來

好的,講到這里大家是不是就覺得很困惑了,為什么會這樣呢?

那我現(xiàn)在就好好給大家講一下了,原來這里面還涉及到了一個概念

緩沖區(qū)

緩沖區(qū)又稱為緩存,它是內(nèi)存空間的一部分。也就是說,在內(nèi)存空間中預(yù)留了一定的存儲空間,這些存儲空間用來緩沖輸入或輸出的數(shù)據(jù),這部分預(yù)留的空間就叫做緩沖區(qū)。

那么這個和我們的getchar又有什么聯(lián)系呢?

當然有聯(lián)系,當我們調(diào)用了getchar函數(shù)時候,這個函數(shù)內(nèi)部其實是這樣做的:

他此時會先從緩存區(qū)中讀一遍,此時讀完之后發(fā)現(xiàn),緩存區(qū)中沒有數(shù)據(jù),他就會等待外部輸入,光標此時就會一閃一閃的~ 

當我們外部輸入了字符之后,然后我們就會敲回車結(jié)束,這時候我們輸入的字符其實就直接全部存在了緩存區(qū)中。

假設(shè)我此時輸入了字符ABCD,然后回車結(jié)束,然后此時緩存區(qū)中就有了ABCD\n

注意,有意思的事情來了,還有\(zhòng)n ???哈哈哈哈接著往下看

緩沖區(qū)帶來的問題

C語言中的getchar()該怎么使用

大家仔細看一下有沒有發(fā)現(xiàn),為什么我getchar沒有輸入字符呢 ?

其實不是我沒有輸入字符,只是在我輸入完scanf的字符之后,回車結(jié)束這個scanf的輸入,然后奇怪的事情發(fā)生了,程序就直接結(jié)束了,是的,跳過了getchar輸入字符這個過程。

大家有沒有覺得奇怪?

這就是我剛才上面給大家提到的 \n

是這樣的,當我此時調(diào)用了scanf函數(shù)之后,我外部輸入了 ABCD,然后輸入完ABCD之后呢我要結(jié)束輸入,然后我們就會去敲回車,注意?。∵@個回車其實也是一個字符,然后他也會連同我前面輸入的ABCD一起放到緩存區(qū),也就是說此時緩存區(qū)中就有了ABCD\n 

我們做一個小小的測試就知道了

C語言中的getchar()該怎么使用

看到這個打印的結(jié)果,大家明白了吧

getchar工作原理

原來調(diào)用getchar函數(shù)的時候,它其實是直接從緩存區(qū)中讀,如果緩存區(qū)中有數(shù)據(jù),他就會直接拿走第一個,然后他的使命也就結(jié)束了。其實這里呢就是上面scanf在緩存區(qū)中拿走了ABCD,然后還剩下一個 10,這個10其實是\n ,是它在ASCII碼中的表示。于是這個剩下的\n就在緩存區(qū)中存下去了,然后他此時遇到了getchar函數(shù),然后getchar在緩存區(qū)中讀,發(fā)現(xiàn):誒,還剩一個\n,那么我就直接拿走,然后他的使命也就便結(jié)束了,所以就出現(xiàn)了不會等待我們外部輸入的那種情況了。

那么我們可以解決這個問題嗎?

解決緩沖區(qū)帶來的問題之清空緩存區(qū)

明白了緩沖區(qū)和getchar的聯(lián)系之后,其實我們想解決就很好辦了

我們只需要在getchar讀取之前在插入一個getchar函數(shù),也就是說讓他在下一次真正getchar讀取之前,我們先再用一個getchar函數(shù)讀一下那個緩存區(qū)剩下的\n,這樣下一次我們真正的getchar讀取時候,緩存區(qū)就空了。

C語言中的getchar()該怎么使用

好了getchar的工作原理我們徹底明白了,那么我們在回到最初的那個疑惑上面。 

解決最初的困惑

C語言中的getchar()該怎么使用

第一次循環(huán):首先緩存區(qū)為空,光標閃爍,然后等待我的輸入

我輸入了一個字符A,然后我繼續(xù)輸入了回車結(jié)束,那么我此時其實輸入了兩個字符,一個字符A,一個字符 \n,此時他們都被存放在了緩存區(qū)。然后緩存區(qū)有了數(shù)據(jù)之后,光標此時不在閃爍,getchar函數(shù)便開始直接讀取,然后在這一次循環(huán)中,getchar函數(shù)讀取到了一個字符A,然后將它給到ch,然后條件表達式為真(不等于ctrl+z),所以執(zhí)行打印ch,然后打印出了一個字符A。

第二次循環(huán):這時候緩存區(qū)還殘留了一個\n,光標不閃爍,getchar也不會等待外部輸入

那么此時getchar直接讀取到這個緩存區(qū)中的\n,繼續(xù)給到ch,然后表達式還是為真,所以繼續(xù)打印這個ch,此時因為ch已經(jīng)是被換掉了\n,所以打印換行,光標位置發(fā)生改變。

第三次循環(huán):緩存區(qū)為空,getchar讀取不到數(shù)據(jù),光標閃爍,getchar等待外部輸入數(shù)據(jù)。

至此我們在接著往下看

C語言中的getchar()該怎么使用

 第一次循環(huán):緩存區(qū)為空,getchar讀取不到緩存區(qū)的數(shù)據(jù),于是光標閃爍,getchar等待外部輸入數(shù)據(jù)。

此時我輸入了一串ABC,然后回車結(jié)束輸入。此時緩存區(qū)中便有了字符ABCD\n,然后getchar讀取第一個字符A,然后將它給到ch,然后條件表達式為真,打印了ch,于是第一個A就出來了。

第二次循環(huán):緩存區(qū)還剩余BC\n,getchar直接讀取

此時getchar讀取到字符B,然后給到ch,條件表達式為真,繼續(xù)打印ch,此時便得到了AB。

第三次循環(huán):緩存區(qū)還剩余C\n,getchar直接讀取

然后還是一樣getchar讀取到C,然后給到ch,之后表達式為真,打印出來了ch,然后經(jīng)過這一次循環(huán)就得到了ABC

第四次循環(huán):緩存區(qū)還剩余一個\n,最后打印這個\n,于是光標下一行。

最終結(jié)果就得到了ABC

然后我再次輸入 ctrl+Z

于是緩存區(qū)存在了ctrl+z(EOF),然后getchar去讀取,然后給到ch,然后表達式判斷,條件為假,ch==EOF,所以循環(huán)跳出,程序結(jié)束。

getchar函數(shù)是直接從緩存區(qū)中讀取數(shù)據(jù),如果緩存區(qū)中有數(shù)據(jù),則直接讀取第一個數(shù)據(jù),如果沒有數(shù)據(jù),那么就光標閃爍,等待外部輸入數(shù)據(jù)。

要非常注意的是,我們其他地方輸入的回車也會被存在緩存區(qū)當成一個字符,然后后面getchar也會將其直接讀出,在這個地方很容易出錯!

感謝大家的閱讀,以上就是“C語言中的getchar()該怎么使用”的全部內(nèi)容了,學(xué)會的朋友趕緊操作起來吧。相信億速云小編一定會給大家?guī)砀鼉?yōu)質(zhì)的文章。謝謝大家對億速云網(wǎng)站的支持!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI