scanf(),gets(),getchar()

----------------------------------------------------

| 問題描述一:(分析scanf()和getchar()讀取字符)? |

--------------------------------------------------

scanf(), getchar()等都是標(biāo)準(zhǔn)輸入函數(shù)宣蔚,一般人都會(huì)覺得這幾個(gè)函數(shù)非常簡單帆喇,沒什么特殊的糕韧。但是有時(shí)候卻就是因?yàn)槭褂眠@些函數(shù)除了問題,卻找不出其中的原因。下面先看一個(gè)很簡單的程序:

程序1:

? ? ? ? int main()

? ? ? ? {

? ? ? ? ? ? ? char ch1, ch2;

? ? ? ? ? ? ? scanf("%c", &ch1);

? ? ? ? ? ? ? scanf("%c", &ch2);

? ? ? ? ? ? ? printf("%d? %d\n", ch1, ch2);

? ? ? ? ? ? ? return 0;

? ? ? ? }

程序2:

? ? ? ? int main()

? ? ? ? {

? ? ? ? ? ? ? char ch1, ch2;

? ? ? ? ? ? ? ch1 = getchar();

? ? ? ? ? ? ? ch2 = getchar();

? ? ? ? ? ? ? printf("%d? %d\n", ch1, ch2);

? ? ? ? ? ? ? return 0;

? ? ? ? }

? 程序的本意很簡單儡羔,就是從鍵盤讀入兩個(gè)字符程癌,然后打印出這兩個(gè)字符的ASCII碼值。可是執(zhí)行程序后會(huì)發(fā)現(xiàn)除了問題:當(dāng)從鍵盤輸入一個(gè)字符后莉钙,就打印出了 結(jié)果廓脆,根本就沒有輸入第二個(gè)字符程序就結(jié)束了。例如用戶輸入字符'a', 打印結(jié)果是97磁玉,10停忿。這是為什么呢?

【分析】:

? ? 首先我們呢看一下輸入操作的原理蚊伞, 程序的輸入都建有一個(gè)緩沖區(qū)席赂,即輸入緩沖區(qū)。一次輸入過程是這樣的时迫,當(dāng)一次鍵盤輸入結(jié)束時(shí)會(huì)將輸入的數(shù)據(jù)存入輸入緩沖區(qū)颅停,而cin函數(shù)直接從輸入緩沖區(qū)中 取數(shù)據(jù)。正因?yàn)閏in函數(shù)是直接從緩沖區(qū)取數(shù)據(jù)的掠拳,所以有時(shí)候當(dāng)緩沖區(qū)中有殘留數(shù)據(jù)時(shí)癞揉,cin函數(shù)會(huì)直接取得這些殘留數(shù)據(jù)而不會(huì)請求鍵盤輸入,這就是例子 中為什么會(huì)出現(xiàn)輸入語句失效的原因碳想!

? ? 其實(shí)這里的10恰好是回車符烧董!這是因?yàn)閟canf()和getchar()函數(shù)是從輸入流緩沖區(qū)中讀取值的,而并非從鍵盤(也就是終端)緩沖區(qū)讀取胧奔。而讀 取時(shí)遇到回車(\n)而結(jié)束的逊移,這個(gè)\n會(huì)一起讀入輸入流緩沖區(qū)的,所以第一次接受輸入時(shí)取走字符后會(huì)留下字符\n龙填,這樣第二次的讀入函數(shù)直接從緩沖區(qū)中 把\n取走了胳泉,顯然讀取成功了,所以不會(huì)再從終端讀妊乙拧扇商!這就是為什么這個(gè)程序只執(zhí)行了一次輸入操作就結(jié)束的原因!

----------------------------------------------------

|? 問題描述二:(分析scanf()和gets()讀取字符串)? |

----------------------------------------------------

首先我們看一下scanf()讀取字符串的問題:

程序3:

? ? ? ? int main()

? ? ? ? {

? ? ? ? ? ? ? char str1[20], str2[20];

? ? ? ? ? ? ? scanf("%s",str1);

? ? ? ? ? ? ? printf("%s\n",str1);? ?

? ? ? ? ? ? ? scanf("%s",str2);?

? ? ? ? ? ? ? printf("%s\n",str2);?

? ? ? ? ? ? ? return 0;

? ? ? ? }

程序的功能是讀入一個(gè)字符串輸出宿礁,在讀入一個(gè)字符串輸出案铺。可我們會(huì)發(fā)現(xiàn)輸入的字符串中不能出現(xiàn)空格梆靖,例如:

測試一輸入:

Hello world!

輸出:

Hello

world!

【分 析】到此程序執(zhí)行完畢控汉,不會(huì)執(zhí)行第二次的讀取操作!這個(gè)問題的原因跟問題一類似返吻,第一次輸入Hello world!后姑子,字符串Hello world!都會(huì)被讀到輸入緩沖區(qū)中,而scanf()函數(shù)取數(shù)據(jù)是遇到回車测僵、空格街佑、TAB就會(huì)停止,也就是第一個(gè)scanf()會(huì)取出"Hello", 而"world!"還在緩沖區(qū)中沐旨,這樣第二個(gè)scanf會(huì)直接取出這些數(shù)據(jù)森逮,而不會(huì)等待從終端輸入。

測試二:

Hello[Enter]

Hello[輸出]

world[Enter]

world[輸出]

【分析】程序執(zhí)行了兩次從鍵盤讀入字符串磁携,說明第一次輸入結(jié)束時(shí)的回車符被丟棄吊宋!即:scanf()讀取字符串會(huì)舍棄最后的回車符!

我們再看一下gets()讀取字符串的情況:

用scanf來讀取一個(gè)字符串時(shí)颜武,字符串中是不可以出現(xiàn)空格的,一旦出現(xiàn)空格拖吼,后面的數(shù)據(jù)就會(huì)舍棄殘留在緩沖區(qū)中鳞上。其實(shí)有另外一個(gè)函數(shù)是可以接受空格的,那就是gets()吊档,下面我們看一下這個(gè)函數(shù)的應(yīng)用篙议,我們把程序3改動(dòng)一下:

? ? int main()

? ? {

? ? ? ? ? char str1[20], str2[20];

? ? ? ? ? gets(str1);

? ? ? ? ? printf("%s\n",str1);? ?

? ? ? ? ? gets(str2);?

? ? ? ? ? printf("%s\n",str2);?

? ? ? ? ? return 0;

? ? }

【分析】顯然與上一個(gè)程序的執(zhí)行情況不同,這次程序執(zhí)行了兩次從鍵盤的讀入怠硼,而且第一個(gè)字符串取了Hello world! 接受了空格符鬼贱,而沒有像上一個(gè)程序那樣分成了兩個(gè)字符串!所以如果要讀入一個(gè)帶空格符的字符串時(shí)因該用gets(), 而不宜用scanf()!

--------------------------------------------------------

| 問題描述三:(getchar()暫停程序香璃,查看程序執(zhí)行結(jié)果)|

--------------------------------------------------------

? ? 不知道大家有沒有遇到過這樣的問題这难,有的編譯器程序執(zhí)行完后的結(jié)果界面不會(huì)停下而是一閃就沒了,以至于看不到執(zhí)行結(jié)果葡秒。所以很多人在程序最后加上 getchar()語句姻乓,目的是想讓程序執(zhí)行完后停下來,等待從終端接收一個(gè)字符再結(jié)束程序眯牧√Q遥可是發(fā)現(xiàn)有時(shí)候這樣根本沒用,程序照樣跳出去了学少。這是為什么 呢剪个?

【分析】原因跟上面例子講的一樣,是因?yàn)檩斎刖彌_區(qū)中還有數(shù)據(jù)版确,所以getchar()會(huì)成果讀到數(shù)據(jù)扣囊,所以就跳出了!

------------------

|? 【總結(jié)】? |

------------------

第一:要注意不同的函數(shù)是否接受空格符阀坏、是否舍棄最后的回車符的問題!

讀取字符時(shí):

scanf()以Space如暖、Enter、Tab結(jié)束一次輸入忌堂,不會(huì)舍棄最后的回車符(即回車符會(huì)殘留在緩沖區(qū)中)盒至;

getchar()以Enter結(jié)束輸入,也不會(huì)舍棄最后的回車符;

讀取字符串時(shí):

scanf()以Space枷遂、Enter樱衷、Tab結(jié)束一次輸入

gets()以Enter結(jié)束輸入(空格不結(jié)束),接受空格酒唉,會(huì)舍棄最后的回車符矩桂!

第二:為了避免出現(xiàn)上述問題,必須要清空緩沖區(qū)的殘留數(shù)據(jù)痪伦,可以用以下的方法解決:

方法1:C語言里提供了函數(shù)清空緩沖區(qū)侄榴,只要在讀數(shù)據(jù)之前先清空緩沖區(qū)就沒問題了!

? ? ? 這個(gè)函數(shù)是fflush(stdin)网沾。

方法2:自己取出緩沖區(qū)里的殘留數(shù)據(jù)癞蚕。

(說實(shí)話這個(gè)語句我也沒看懂,呵呵辉哥!為什么格式控制是這樣的桦山!希望高手指點(diǎn)一下!)

? ? ? scanf("%[^\n]",string);

————————————————

版權(quán)聲明:本文為CSDN博主「zqixiao_09」的原創(chuàng)文章醋旦,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議恒水,轉(zhuǎn)載請附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.net/zqixiao_09/article/details/50189477

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末饲齐,一起剝皮案震驚了整個(gè)濱河市钉凌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌捂人,老刑警劉巖甩骏,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異先慷,居然都是意外死亡饮笛,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門论熙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來福青,“玉大人,你說我怎么就攤上這事脓诡∥尬纾” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵祝谚,是天一觀的道長宪迟。 經(jīng)常有香客問我,道長交惯,這世上最難降的妖魔是什么次泽? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任穿仪,我火速辦了婚禮,結(jié)果婚禮上意荤,老公的妹妹穿的比我還像新娘啊片。我一直安慰自己,他們只是感情好玖像,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布紫谷。 她就那樣靜靜地躺著,像睡著了一般捐寥。 火紅的嫁衣襯著肌膚如雪笤昨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天握恳,我揣著相機(jī)與錄音咬腋,去河邊找鬼。 笑死睡互,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的陵像。 我是一名探鬼主播就珠,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼醒颖!你這毒婦竟也來了妻怎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤泞歉,失蹤者是張志新(化名)和其女友劉穎逼侦,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腰耙,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡榛丢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挺庞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晰赞。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖选侨,靈堂內(nèi)的尸體忽然破棺而出掖鱼,到底是詐尸還是另有隱情,我是刑警寧澤援制,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布戏挡,位于F島的核電站,受9級(jí)特大地震影響晨仑,放射性物質(zhì)發(fā)生泄漏褐墅。R本人自食惡果不足惜拆檬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掌栅。 院中可真熱鬧秩仆,春花似錦、人聲如沸猾封。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晌缘。三九已至齐莲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間磷箕,已是汗流浹背选酗。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留岳枷,地道東北人芒填。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像空繁,于是被迫代替她去往敵國和親殿衰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • C/C++輸入輸出流總結(jié) 前兩天寫C++實(shí)習(xí)作業(yè)盛泡,突然發(fā)現(xiàn)I/O是那么的陌生闷祥,打了好長時(shí)間的文件都沒有打開,今天終...
    LuckTime閱讀 1,731評(píng)論 0 6
  • 在C語言中,五種基本數(shù)據(jù)類型存儲(chǔ)空間長度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 3,342評(píng)論 0 2
  • 一、輸入和輸出流 C 語言的標(biāo)準(zhǔn)輸入輸出函數(shù)都是獨(dú)立于設(shè)備的,不需要考慮如何在特定設(shè)備上傳輸數(shù)據(jù)蚜迅;C 語言的庫函數(shù)...
    seraphzxz閱讀 1,130評(píng)論 0 51
  • 頭文件stdio.hc語言的標(biāo)準(zhǔn)輸入輸出耘柱,常用printf;scanfiostreamc++語言的標(biāo)準(zhǔn)輸入輸出,重...
    bobobe閱讀 2,403評(píng)論 0 2
  • 程序是人機(jī)交互的媒介,有輸出必然也有輸入,第三章我們講解了如何將數(shù)據(jù)輸出到顯示器上,本章我們開始講解如何從鍵盤輸入...
    夢凡塵閱讀 1,507評(píng)論 0 2