C語言 getchar()原理及易錯點解析
一.getchar()系列
1.getchar()工作原理及作用
工作原理:getchar()是stdio.h中的庫函式,它的作用是從stdin流中讀入一個字元,也就是說,如果stdin有資料的話不用輸入它就可以直接讀取了,第一次getchar()時,確實需要人工的輸入,但是如果你輸了多個字元,以後的getchar()再執行時就會直接從緩衝區中讀取了。
實際上是 輸入裝置->記憶體緩衝區->getchar()
你按的鍵是放進緩衝區了,然後供程式getchar()
你有沒有試過按住很多鍵然後等一會兒會滴滴滴滴響,就是緩衝區滿了,你後頭按的鍵沒有存進緩衝區.
鍵盤輸入的字元都存到緩衝區內,一旦鍵入回車,getchar就進入緩衝區讀取字元,一次只返回第一個字元作為getchar函式的值,如果有迴圈或足夠多的getchar語句,就會依次讀出緩衝區內的所有字元直到’\n’.要理解這一點,之所以你輸入的一系列字元被依次讀出來,是因為迴圈的作用使得反覆利用getchar在緩衝區裡讀取字元,而不是getchar可以讀取多個字元,事實上getchar每次只能讀取一個字元.如果需要取消’\n’的影響,可以用getchar();來清除,這裡getchar();只是取得了’\n’但是並沒有賦給任何字元變數,所以不會有影響,相當於清除了這個字元.
作用1:從緩衝區讀走一個字元,相當於清除緩衝區。
作用2:前面的scanf()在讀取輸入時會在緩衝區中留下一個字元’\n’(輸入完按回車鍵所致),所以如果不在此加一個getchar()把這個回車符取走的話,接下來的scanf()就不會等待從鍵盤鍵入字元,而是會直接取走這個“無用的”回車符,從而導致讀取有誤。
2.使用getchar()清理回車\n
1 #include <stdio.h> 2 3 int main(void){ 4 char m[40]; 5 char n; 6 printf("please input first str:\n"); //提示使用者輸入第一個字串 7 scanf("%s",m); //獲取使用者第一個輸入字串 8 printf("you input str is :%s\n",m); //輸出使用者的輸入的第一個字串 9 printf("input second char :\n"); //提示使用者輸入第二個字元 10 scanf("%c",&n); //獲取使用者的第二個字元 11 printf("now you input second char is :%c\n",n);//輸出使用者輸入的第二個字元 12 return 0; 13 14 }
Output:
1 please input first str: 2 abc 3 you input str is :abc 4 input second char : 5 now you input second char is : 6 7 Program ended with exit code: 0
問題:我們第一次輸入abc後成功打印出來了you input str is :abc
,但是執行到printf("input second char :\n");
時,還沒等到第二次輸入就打印出來了。這是為什麼??
原因:
其實在我們第一次輸入並按下回車的時候,控制檯一共獲得了四個字元,分別是:a、b、c、回車(enter)。但是因為scanf()方法遇到非字元的時候會結束從控制檯的獲取,所以在輸入’abc’後,按下 ‘回車(enter)’ 的同時,將’abc’這個值以字串的形式賦值給了型別為 ‘char’ 的 ‘m’ 陣列,將使用過後的字串: ‘回車(enter)’ 儲存在控制檯輸入的緩衝區,然後繼續執行下一段輸出程式碼,然後又要求使用者輸入。此時,因為上一次被使用過後的字串被儲存在緩衝區,現在scanf()方法從控制檯的緩衝區獲取上一次被使用過後的字串,並只擷取第一個字元: ‘回車(enter)’ ,此時控制檯緩衝區才算使用完了。所以在看似被跳過的輸入,其實已經scanf()方法已經獲取了我們的輸入了,這個輸入就是一個 ‘回車(enter)’ 。
解決問題:
使用getchar()方法,清除掉abc後面的快取(回車enter)。
1 #include <stdio.h> 2 3 int main(void){ 4 char m[40]; 5 char n; 6 printf("please input first str:\n"); //提示使用者輸入第一個字串 7 scanf("%s",m); //獲取使用者第一個輸入字串 8 printf("you input str is :%s\n",m); //輸出使用者的輸入的第一個字串 9 getchar(); 10 printf("input second char :\n"); //提示使用者輸入第二個字元 11 scanf("%c",&n); //獲取使用者的第二個字元 12 printf("now you input second char is :%c\n",n);//輸出使用者輸入的第二個字元 13 return 0; 14 15 }
Output:
1 please input first str: 2 abc 3 you input str is :abc 4 input second char : 5 de 6 now you input second char is :d 7 Program ended with exit code: 0
3.使用getchar()清理快取
文章結束時留了一個問題:如果在第一次輸入ab後加一個空格再回車,又會出現原來的問題,即程式只輸出了ab後就自動跳過下一次的輸入之間退出了,控制檯輸出如下圖所示。
原因:
在獲取使用者第一個輸入字串時,scanf("%s",&m);,我們用%s作為轉換說明,%s的作用是“把輸入解釋成字串。從第一個非空白字元開始,到下一個空白字元之前的所有字元都是輸入。”所以scanf把輸入的ab空格+回車就理解為ab+回車(ab後面沒有空格),但是依然以ab空格+回車的形式儲存在快取區。
我們輸入ab空格+回車,在快取區是這樣存放的:
其中,第三格存放的為空格鍵。
當程式執行完 getchar();後,只清除了第三格中的空格鍵,因為一次執行getchar();只清除一個快取,留下了第四格中的回車鍵,因此再次出現了同樣的問題。
解決問題:那麼就是說只要執行兩次getchar();
,清除掉第三格和第四格就可以正常了。
#include <stdio.h> int main(void){ char m[40]; char n; printf("please input first str:\n"); //提示使用者輸入第一個字串 scanf("%s",m); //獲取使用者第一個輸入字串 printf("you input str is :%s\n",m); //輸出使用者的輸入的第一個字串 getchar(); //第一次清除快取 getchar(); //第二次清除快取 printf("input second char :\n"); //提示使用者輸入第二個字元 scanf("%c",&n); //獲取使用者的第二個字元 printf("now you input second char is :%c\n",n);//輸出使用者輸入的第二個字元 return 0; }
本文來自部落格園,作者:Colin_Cora,轉載請註明原文連結:https://www.cnblogs.com/Colincora/p/15490035.html