c語言scanf函式輸入時鍵盤緩衝區n的問題

2021-12-19 08:17:12 字數 5548 閱讀 9567

1樓:匿名使用者

你首先要明白,從鍵盤讀入鍵盤緩衝區(buffer)的資料都是以ascii碼儲存的(包括回車)。

程式1#include "stdio.h"

void main()

鍵盤輸入

97《回車》

第一次回車後,buffer中的ascii:39h,37h,0ah(0a是換行的ascii), scanf會根據格式字串中的第一個%d對buffer按位元組順序讀取,當讀取到0a時,認為%d型的資料結束,此時把已經讀取到的39h,37h依據%d轉為整型資料97儲存在字元型變數a中。(這裡是除去了掃描截止點0ah)

此時buffer中已經無任何資料了。

96《回車》

第二次回車後,按同樣的流程,scanf會根據格式字串中的第二個%d對buffer按位元組順序讀取。最終b得到96.

此時buffer中已經無任何資料了。

輸出97 96

程式2#include "stdio.h"

void main()

鍵盤輸入

9《回車》buffer:39h,0ah

因為scanf會按照第一個%c格式掃描buffer(只掃描一個位元組就結束),然後把掃描到的39h直接送到變數a(當以%d格式讀出來時,39h就是57)

此時,buffer中只有:0ah。

然後,scanft又遇到第二個%c,繼續掃描buffer,得到0ah並送入變數b.

此時buffer中已經無任何資料了

輸出57 10

程式3#include "stdio.h"

void main()

鍵盤輸入

abc《回車》

第一次回車後,buffer:61h,62h,63h,0ah。

scanf會按照%s的格式對buffer按位元組順序掃描,當掃描到0ah時,結束掃描(按照%s的要求,空格20h也是掃描結束點)。

然後把掃描到的(除去最後一個判斷掃描截至的位元組0ah)資料直接送入以a為起始地址的字串。

此時,buffer無任何資料了。

def《回車》

第二次回車後,buffer:65h,66h,67h,0ah.掃描的流程與上面的完全一致。

輸出abc def

程式4#include

void main()

鍵盤輸入

1《回車》,

這裡scanf執行了兩次(i==0時,與i==1時),而且每次都是想對j賦值。

第一次scanf,按%c的要求,只掃描buffer中的一個位元組,但是buffer中並不資料,於是要求鍵盤輸入資料到buffer,此時的1《回車》代表向buffer中輸入了:31h,0ah。

然後按%c的要求,只掃描buffer中的一個位元組:31h,並將它直接送入變數j.

此時,buffer中還留下:0ah。

第二次scanf要求鍵盤輸入資料,按%c的要求,只掃描buffer中的一個位元組:0ah,並將它直接送入變數j.

此時,buffer無資料了。

最後,你用%d格式輸出j的值(0ah換成整型就是10)

輸出10

程式5#include

void main()

1《回車》2的情況:

scanf會按照格式控制字串的要求,順序掃描buffer.

但是你其中有一個空格,這個很特殊,我也是第一次發現這個問題(一般我都不會在scanf中加入任何常量字元)

我測試了一下:我發現這個空格有吸收回車(0ah)和空格(20h)的「神奇功效」,吸收之後再要求buffer給一個位元組,直到這個位元組不是0ah或者 20h,此時把這個位元組交給下一個格式字串。

第一次迴圈時遇到格式字串空格,就掃描buffer中的一個位元組,但是buffer中無資料,要求從鍵盤輸入資料:1〈回車〉,buffer中有資料了——31h,0ah。再讀取到位元組31h,scanf發現這個並不是0ah/20h,就把這個位元組31h交給格式字元%c處理。

迴圈結束,此時buffer裡面還有:0ah.

第二次迴圈時遇到格式字串空格,就掃描buffer中的一個位元組——0ah,發現是0ah/20h,於是就要求buffer再來一個位元組。此時buffer裡面已經沒有資料了,要求鍵盤輸入:2.

buffer中有資料了——32h,0ah。於是再讀一個位元組31h,scanf發現這個並不是0ah/20h,就把這個位元組32h交給格式字元%c處理(j最終得到32h)。

迴圈結束,此時buffer裡面還有:0ah.

這裡有一篇關於printf的帖子

程式6#include "stdio.h"

void main()

鍵盤輸入

1《回車》

問題5:

你的編譯器vc認為%d資料應該是4個位元組,但是你採用的是%c讀資料,

scanf("%c",&a);此句讀到的是1的ascii碼:31h.然後把31h直接送入地址&a(而並沒有改寫a的三個高位元組地址)。

scanf("%c",&b);同理。

你可以用printf("a=%x,b=%x\n",a,b);來驗證我說的。它們的最低位元組肯定是31h,0ah。

ps1:

當你把 int a;int b;放在main()外進行定義時,a,b的初值就是0。此時你會得到正確的結果。

當你把 int a;int b;放在main()內進行定義時,a,b不會被初始化(它們的三個三個高位元組地址的內容是不確定的),你就會得到上面錯誤的結果。(定義的動態變數都不會被初始化,靜態變數會被初始化為0)

ps2:以下也是不正確的用法。

char c;

scanf("%d",&c);/當你用%d給c賦值時,會對從&c開始的連續4個位元組進行賦值。當從buffer得到的值是在一個位元組範圍內(-128~127),下面是可以正常輸出的。但是不管怎樣,這樣做是很危險的——越界。

printf("%d",c);

***************==請你測試下這個程式********************====

#include "stdio.h"

void main()

/*如果得到的結果是00 00 00 01 02就說明我的結論是正確的(258的轉為16進位制數就是00 00 01 02h,然後scanf會把這個數放入以c為起始地址的)

***************=以下程式也是********************==

#include "stdio.h"

void main()

2樓:

你忽略了一個問題,就是scanf的格式控制符的用處。%d只接受整數的輸入,%c和%s可以接受字元的輸入,其中也包括\n等轉義字元。因此「scanf輸入遇到空格、跳格、回車才會從緩衝區往變數送字元」不是絕對的。

清楚了%c %s可以接受字元,問題就解決了。

至於程式6,我不用vc不清楚,但gcc是可以通過的

3樓:

getchar 和 %c 格式 涉及 '\n',常使初學者困擾。

清除緩衝區殘存資訊其實很簡單:

fflush(stdin);

就可以了,這樣,後面的讀就不受前面的影響。

鍵入資料的格式應當與輸入語句格式相配:

char a; 相當1位元組整型。所以可以用%d格式輸入。用%d格式,預設分隔符是所有的 white-spaces

用%c格式輸入,則按ascii字元考慮。無分隔符。必要時用fflush(stdin);清除緩衝區

%s 是 字串格式,預設分隔符是所有的 white-spaces,輸入後自動有結束符"\0".

c語言中用scanf函式輸入字元時,為什麼要在輸入控制符%c前面加空格?用scanf還有哪些要注意?

4樓:愛佳佳的恐龍

如果scanf中%d是連著寫的如「%d%d%d」,在輸入資料時,資料之間不可以用逗號分隔,只能用空白字元(空格或tab鍵或者回車鍵)分隔。

「2 (空格)3(tab) 4」 或 「2(tab)3(回車)4」等。若是「%d,%d,%d」,則在輸入資料時需要加「,」,如「2,3,4」。

比如scanf(" %c" ,&c);

你輸入了' a'(a前面有個空格),a就能被c接受。但控制符前如果沒空格,那c就接受了空格,明白了沒?這個可以防止誤操作,忽略空格輸入,接受第一個非空格輸入。

5樓:黑白say晚安

加空格遮蔽了空白字元。

%c前沒空格,scanf()將讀取標準輸入流中的第一個字元,%c前有空格,scanf()則讀取標準輸入流中第一個非空白字元。

使用scanf函式時應該注意的問題:

scan:掃描       f :format,格式1、整數和小數分別使用使用控制符%d %lf 表示(float除外,用%f)。

2、引數前面使用&符號,&號前要空格。

3、scanf輸入語句中替換符後不能加空格,也不能加\n。

4、scanf()中的變數必須使用地址。

5、scanf()的格式控制串可以使用空白字元或其它非空白字元,使用空白字元會使scanf()函式在讀操作中略去輸入中的一個或多個空白字元。使用非空白字元會使scanf()函式在讀入時剔除掉與這個非空白字元相同的字元。

6、在用"%c"輸入時,空格和「轉義字元」均作為有效字元。

6樓:匿名使用者

%c前面的空格就是用來遮蔽空白符的,

首先必須要知道c語言 scanf() 函式的特性,以及scanf()與緩衝區、標準輸入流之間的聯絡。在此之前,先介紹兩個專業術語。

1.緩衝區

緩衝區是一塊存放臨時輸入資料的記憶體,我們在鍵盤上輸入資料之所以不會馬上顯示,就是因為資料存放在了緩衝區,在上面例子中,當我們按下回車鍵後,緩衝區的資料會傳送到標準輸入流。

2.標準輸入流

標準輸入流(stdin)是檔案指標,scanf()就是從標準輸入流或許資料。

以上面**為例,當執行到scanf()時,

電腦開始執行以下操作:

開始等待使用者輸入

2.當我們輸入資料,在按下回車鍵前會把資料儲存在緩衝區,按下回車鍵後,會把資料以及換行符(\n)一起傳送到標準輸入流(stdin)中,

scanf()就是從標準輸入流中或許資料,上面第一個scanf()要讀入一個整數,它從標準輸入流中查詢,跳過空白符(空格、換行符、製表符)

3.如果遇到數字,則開始讀入,直到遇到非數字的字元結束,最後計算讀取到的數值,儲存到相關變數中。

使用scanf注意事項

1.引數的個數一定要對應

2.輸入的資料型別一定要和所需要的資料型別一致

3.每次呼叫完scanf後,記得呼叫一個getchar()函式

擴充套件資料

1.函式 scanf() 是從標準輸入流stdio (標準輸入裝置,一般指向鍵盤)中讀內容的通用子程式,可以說明的格式讀入多個字元,並儲存在對應地址的變數中。

2.函式的第一個引數是格式字串,它指定了輸入的格式,並按照格式說明符解析輸入對應位置的資訊並儲存於可變引數列表中對應的指標所指位置。

每一個指標要求非空,並且與字串中的格式符一一順次對應。

參考資料

網頁連結

c語言用scanf格式輸入時對輸入的資料格式有什

在scanf格式字串中 指定分隔符 比如要用逗號分隔,那就寫逗號 scanf d,d a,b 如果要用空格分隔 那麼可以不寫分隔符 直接scanf d d a,b 本來scanf就是按照你輸入的格式來讀取的,比如1,空格空格2就應該寫成 d,d 1.scanf函式的一般形式 scanf 格式控制,地...

C語言的scanf 函式問題

scanf的意思就是接受的意思啊。你輸入了換行相當於在此接受啊。在printf函式中的 代表換行符,轉義字元只在printf中有意義,在scanf函式中無意義。像樓主這種狀況應該輸入 一個數 再按回車鍵。你理解錯誤了,在c語言裡面 printf 函式是格式化輸出函式。scanf 函式是格式化輸入函式...

C語言中for迴圈scanf輸入的為題

因為你非常有bai可能每輸入一個字du符就zhi按了一次回車,而回車其實dao也是一個內 字元。在 scanf c char i 語句容後加上一句getchar 就可以啦!如果前面有輸入資料的情況。把getchar 放在 scanf c char i 之前。經過測試?怎麼測試的?測試都不用先通過編譯...