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;
    
}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM