您好,登錄后才能下訂單哦!
這篇文章主要介紹了c語(yǔ)言中緩沖區(qū)問(wèn)題的示例分析,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
你是不是總會(huì)出現(xiàn)當(dāng)你輸入的時(shí)候(你想的是只輸出一個(gè)內(nèi)容),但是最后卻輸入兩個(gè)。
比如下面這個(gè)例子
那這到底是是哪出了問(wèn)題呢?
沒(méi)錯(cuò)這就是關(guān)于緩沖區(qū)的問(wèn)題。
我們先仔細(xì)了解這個(gè)題目
判斷字母是否為元音字母包括大小寫(xiě)。
看代碼實(shí)現(xiàn)(錯(cuò)誤的)
#include<stdio.h> int main() { int i = 0; char ch = 0; char yyzm[20] = { 'a','A','e','E','i','I','o','O','u','U' }; while(scanf("%c", &ch)!=EOF) { for (i = 0; i < 10; i++) { if (ch == yyzm[i]) { printf("元音字母\n"); break; } } if (i == 10) { printf("輔音字母\n"); } } return 0; }
我們一般怎么輸入呢?
我們先輸入元音字母o然后在按一下回車,一般輸入都是這樣輸入的到底是哪出了問(wèn)題呢?
沒(méi)錯(cuò)就是那個(gè)回車惹的禍。每當(dāng)我們輸入一個(gè)字母的時(shí)候,scanf讀取字母之后,就會(huì)放入緩沖區(qū)中,回車一下當(dāng)然也會(huì)放個(gè)'\n'字符也就是空格,當(dāng)計(jì)算機(jī)拿取字符的時(shí)候先拿走一個(gè)字符,接著看里面還有沒(méi)有字符,如果有字符就會(huì)繼續(xù)讀取,如果沒(méi)有則進(jìn)行下面的內(nèi)容。
在我們這個(gè)代中由于是多次輸入數(shù)據(jù),就會(huì)讀入字符后第一個(gè)if語(yǔ)句結(jié)束,如果還有字符的話,計(jì)算機(jī)就會(huì)繼續(xù)拿字符,這時(shí)就拿了一個(gè)'\n','\n'不是元音字母就會(huì)進(jìn)入下一個(gè)if語(yǔ)句輸出。
那我們?nèi)绾谓鉀Q呢?
在后面加入getchar(),它的作用就是清理緩存區(qū),由于輸入字符,計(jì)算機(jī)是一個(gè)一個(gè)字符讀取的,又因?yàn)槲覀兌啻屋斎?,所以getchar總是會(huì)讀取那個(gè)'\n';
我們?cè)趕canf%c后面加個(gè)'\n',由于是一個(gè)一個(gè)讀取字符的,如果后面有'\n',就會(huì)把\n也拿走。
在%c前面加個(gè)空格,這樣做的目的是每次讀取下一個(gè)字符時(shí),就會(huì)把上一個(gè)字符后面的'\n'清理掉。
正確的代碼:
#include<stdio.h> int main() { int i = 0; char ch = 0; char yyzm[20] = { 'a','A','e','E','i','I','o','O','u','U' }; while(scanf(" %c", &ch)!=EOF)//可以在%c后面加個(gè)'\n',也可以在%c前面加個(gè)空格,目的是清理緩沖區(qū) { for (i = 0; i < 10; i++) { if (ch == yyzm[i]) { printf("元音字母\n"); break; } } if (i == 10) { printf("輔音字母\n"); } } //getchar();清理緩沖區(qū) return 0; }
當(dāng)我們用scanf輸入字符串的時(shí)候,如果遇到空格也會(huì)出現(xiàn)問(wèn)題,這時(shí)我們就可以引入另外一個(gè)函數(shù)那就是gets函數(shù)
gets函數(shù)的優(yōu)點(diǎn)與scanf對(duì)比:
gets() 函數(shù)不僅比 scanf 簡(jiǎn)潔,而且,就算輸入的字符串中有空格也可以直接輸入,不用像 scanf 那樣要定義多個(gè)字符數(shù)組。
關(guān)于使用 gets() 函數(shù)需要注意:使用 gets() 時(shí),系統(tǒng)會(huì)將最后“敲”的換行符從緩沖區(qū)中取出來(lái),然后丟棄,所以緩沖區(qū)中不會(huì)遺留換行符。這就意味著,如果前面使用過(guò) gets(),而后面又要從鍵盤(pán)給字符變量賦值的話就不需要吸收回車清空緩沖區(qū)了,因?yàn)榫彌_區(qū)的回車已經(jīng)被 gets() 取出來(lái)扔掉了。(此段話是在網(wǎng)上查到的,整理為復(fù)習(xí)準(zhǔn)備,請(qǐng)見(jiàn)諒)。
我們來(lái)做個(gè)題吧
逆序字符串
#include<stdio.h> #include<string.h> void swap(char* str) { int i = 0; int len = strlen(str); for (i = 0; i < len / 2; i++) { char tmp = 0; tmp = str[i]; str[i] = str[len - i - 1]; str[len - i - 1] = tmp; } printf("%s", str); } int main() { //逆序字符串的內(nèi)容 char str[100]; int i = 0; gets(str); swap(str); return 0; }
比如我們從磁盤(pán)里取信息,我們先把讀出的數(shù)據(jù)放在緩沖區(qū),計(jì)算機(jī)再直接從緩沖區(qū)中取數(shù)據(jù),等緩沖區(qū)的數(shù)據(jù)取完后再去磁盤(pán)中讀取,這樣就可以減少磁盤(pán)的讀寫(xiě)次數(shù),再加上計(jì)算機(jī)對(duì)緩沖區(qū)的操作大大快于對(duì)磁盤(pán)的操作,故應(yīng)用緩沖區(qū)可大大提高計(jì)算機(jī)的運(yùn)行速度。
又比如,我們使用打印機(jī)打印文檔,由于打印機(jī)的打印速度相對(duì)較慢,我們先把文檔輸出到打印機(jī)相應(yīng)的緩沖區(qū),打印機(jī)再自行逐步打印,這時(shí)我們的CPU可以處理別的事情。
現(xiàn)在您基本明白了吧,緩沖區(qū)就是一塊內(nèi)存區(qū),它用在輸入輸出設(shè)備和CPU之間,用來(lái)緩存數(shù)據(jù)。它使得低速的輸入輸出設(shè)備和高速的CPU能夠協(xié)調(diào)工作,避免低速的輸入輸出設(shè)備占用CPU,解放出CPU,使其能夠高效率工作。
緩沖區(qū)的類型
緩沖區(qū) 分為三種類型:全緩沖、行緩沖和不帶緩沖。
1) 全緩沖
在這種情況下,當(dāng)填滿標(biāo)準(zhǔn)I/O緩存后才進(jìn)行實(shí)際I/O操作。全緩沖的典型代表是對(duì)磁盤(pán)文件的讀寫(xiě)。
2) 行緩沖
在這種情況下,當(dāng)在輸入和輸出中遇到換行符時(shí),執(zhí)行真正的I/O操作。這時(shí),我們輸入的字符先存放在緩沖區(qū),等按下回車鍵換行時(shí)才進(jìn)行實(shí)際的I/O操作。典型代表是標(biāo)準(zhǔn)輸入(stdin)和標(biāo)準(zhǔn)輸出(stdout)。
3) 不帶緩沖
也就是不進(jìn)行緩沖,標(biāo)準(zhǔn)出錯(cuò)情況stderr是典型代表,這使得出錯(cuò)信息可以直接盡快地顯示出來(lái)。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“c語(yǔ)言中緩沖區(qū)問(wèn)題的示例分析”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。