為什么連續的scanf會被跳過或不執行


前言-

這幾天再嘗試學一下C語言,對着RUNOOB.com的教程一通操作,還是一臉霧水。問題倒是積累了不少。

正文-

問題一:“為啥我的第二個scanf( )函數自動跳過,不等待我輸入就自己執行了?”

一個很簡單的例子:

#include <stdio.h>
/*試圖兩次利用scanf()函數,先后讀取整型變量a和字符型變量c*/
int main()
{
    int a;
    char c;
    scanf("%d",&a);
    scanf("%c",&c);
    printf("%d %c",a,c); 
}

解析:當我們輸入:123 ↙
會發現程序會“直接”打印整數123,好像並沒有給我們留下時間和空間輸入字符型變量c的值(一開始我也一臉懵B??).
但是,經過調試(啊,萬能的調試!),我們可以發現,其實整型變量c已經讀入了值‘\n’,即ASCII碼為10的字符——換行符;
如調試圖:


a = 123, c= 10'\n'

實際上:

函數scanf( )從標准輸入設備(鍵盤) 讀取輸入的信息,不會直接賦值給變量,而是先儲存到一個緩沖區中;

當程序執行到函數scanf()時,程序會從緩沖區中讀取;
如果緩沖區是空的,才會停滯,光標閃爍,等待鍵盤的輸入.

值得注意的是,scanf()中格式字符串里:
-對於參數%d:會忽略緩沖區開頭的空白符(空格、回車、制表符等)(無論有幾個);
-對於參數 %c:直接讀取緩沖區的第一個字符(無論這個字符是什么);

故,上例中:
1º 向緩沖區中輸入:123\n
2º 語句scanf("%d",&a); 讀取走了123,賦給變量a;
(緩沖區變化:123\n → \n)
3º 語句scanf("%c",&c);讀取走了**\n,賦給變量c**;
(緩沖區變化:\n → 空白)

解決方法:
1º 利用函數getchar( )吃掉回車:在scanf后接一個getchar( );

#include <stdio.h>
int main()
{
    int a;
    char c;
    scanf("%d",&a);
    getchar();/*吃掉回車*/
    scanf("%c",&c);
    printf("%d %c",a,c); 
}

2º 利用函數fflush( )清除緩沖區:如fflush(stdin);

#include <stdio.h>
int main()
{
    int a;
    char c;
    scanf("%d",&a);
    fflush(stdin);/*清除輸入緩沖區*/
    scanf("%c",&c);
    printf("%d %c",a,c); 
}

注意 注意 注意 :

有同學可能用的是新版的vs,可能不支持該方法2;可以試一下替換成rewind(stdin)函數;

或者可以直接一次性讀取兩個數據scanf("%d%*c", &c);——注意星號*哈!
這句話的意思是就是說:讀取一個整數后,丟棄緊跟在整數后邊的一個字符(也就是我們多輸入的“回車符”);

有問題的試一下吧…

 

問題二:“為啥在我輸入數據和回車之后程序沒有反應?”

——在函數scanf( )的格式字符串中加入\n的問題:

#include <stdio.h>
int main()
{
    int a;
    scanf("%d\n",&a);/*注意%d后的\n*/
    printf("%d",a);
}

這種情況下,按照“整型數字 回車”的格式讀取,讀到回車之后,由於緩沖區空白,程序停滯,程序停滯,光標閃爍,等待鍵盤輸入;故,當你輸入一個整數和回車后,a的值不會立即打印,要等再接收到一個非空白符(即非空格、回車、制表符等)的輸入之后,該scanf語句才結束,接着才輸出。

如圖:


解釋:當輸入:123↙ 程序框中換行但並不打印;
繼續輸入:456↙ 此時換行,並且輸出了剛才鍵入的123;

總之,在使用函數scanf( )時,應該心中有一個緩沖區,合理利用相關函數來解決鍵盤緩沖區殘余信息的問題;同時,理解讀取格式,以便搞清楚何時函數scanf( )結束;


原文鏈接:https://blog.csdn.net/HNAKXR/java/article/details/81047391


免責聲明!

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



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