當(dāng)前位置:首頁(yè) > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > 關(guān)于scanf( )函數(shù)使用
1.scanf( )函數(shù)介紹
C庫(kù)中包含了多個(gè)輸入函數(shù),scanf( )是通用的一個(gè),因?yàn)樗梢宰x取不同格式的數(shù)據(jù)。如果想輸入整數(shù)100,就要鍵入字符1、0、0,那么scanf()要做的就是將字符依次轉(zhuǎn)換成數(shù)值。
頭文件:#include<stdio.h>
用法:
int scanf(const char *format, ...);
其調(diào)用格式為: scanf("<格式化字符串>",<地址表>);
例如:scanf(“%d%d”,&a,&b); //a和b為int類(lèi)型變量
%d // 轉(zhuǎn)換說(shuō)明,表明目標(biāo)數(shù)據(jù)類(lèi)型為int型
功能:
scanf()函數(shù)是格式化輸入函數(shù),它從鍵盤(pán)(標(biāo)準(zhǔn)輸入設(shè)備)輸入,讀取輸入字符,根據(jù)格式字符串表明字符輸入流的目標(biāo)數(shù)據(jù)類(lèi)型。
返回值:
scanf()函數(shù)返回成功賦值的數(shù)據(jù)項(xiàng)數(shù),出錯(cuò)時(shí)則返回EOF。
2.轉(zhuǎn)換說(shuō)明
什么是轉(zhuǎn)換說(shuō)明呢?既然scanf( )是標(biāo)準(zhǔn)格式輸入函數(shù),那么輸入的數(shù)據(jù)就要存儲(chǔ)到目標(biāo)變量中,而目標(biāo)變量又會(huì)有很多種類(lèi)型,例如int、char、float等,scanf( )如何區(qū)分呢?于是,轉(zhuǎn)換說(shuō)明出現(xiàn)了,他指明了scanf( )把輸入解釋成什么數(shù)據(jù)類(lèi)型,存儲(chǔ)到相對(duì)應(yīng)的目標(biāo)變量中。就像一家啤酒廠商,生產(chǎn)出的啤酒是雪花啤酒,就要放入雪花啤酒瓶中,淡爽啤酒就要放入淡爽啤酒瓶中,同理轉(zhuǎn)換說(shuō)明就起到了我們輸入的數(shù)據(jù)要解釋成與目標(biāo)變量相對(duì)應(yīng)的數(shù)據(jù)類(lèi)型。
ANSI中scanf( )的轉(zhuǎn)換說(shuō)明
轉(zhuǎn)換說(shuō)明 含義
%c 把輸入解釋成字符
%d 把輸入解釋成有符號(hào)十進(jìn)制整數(shù)
%e、%f、%g、%a 把輸入解釋成浮點(diǎn)數(shù)
%E、%F/、%G、%A 把輸入解釋成浮點(diǎn)數(shù)
%i 把輸入解釋成有符號(hào)的十進(jìn)制整數(shù)
%o 把輸入解釋成有符號(hào)的八進(jìn)制整數(shù)
%p 把輸入解釋成指針
%s 把輸入解釋成字符串
%u 把輸入解釋成無(wú)符號(hào)十進(jìn)制整數(shù)
%x、%X 把輸入解釋成有符號(hào)十六進(jìn)制整數(shù)
3.scanf函數(shù)用法
3.1 輸入整數(shù)(%d)
(1)scanf(“%d%d%d”,&a,&b,&c);
#include <stdio.h>
int main()
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
printf("%d,%d,%d\n",a,b,c);
return 0;
}
1) 輸入:2<enter>3<enter>4<enter>
輸出:2,3,4
2) 輸入:<space> 2 <space> 3 <space> 4 <space>
輸出:2,3,4
※思考與總結(jié)※
scanf函數(shù)每次讀取一個(gè)字符,跳過(guò)所有空白字符,直至遇到第一個(gè)非空白字符才開(kāi)始讀取,因?yàn)橐x取整數(shù),所以希望發(fā)現(xiàn)一個(gè)數(shù)字字符或者一個(gè)符號(hào)(+或-),如何找到一個(gè)數(shù)字或符號(hào),便保存字符,并讀取下一個(gè)字符,直至遇到非數(shù)字字符。如果遇到非數(shù)字字符,便認(rèn)為讀到了末尾,然后scanf把非數(shù)字字符放回輸入。這就意味著程序在下一次讀取輸入時(shí),首先讀到的是上一次讀取丟棄的非數(shù)字字符。
空白字符會(huì)使scanf()函數(shù)在讀操作中略去輸入中的一個(gè)或多個(gè)空白字符,空白符可以是space,tab,newline等等,直到第一個(gè)非空白符出現(xiàn)為止。
<tab> 2 <tab> 3 <tab> 4 <tab> // 輸出同上,<tab>為空白字符
3) 輸入:c<enter>
#include <stdio.h>
int main()
{
int a,b,c;
printf("%d,%d,%d\n",a,b,c);//增加一行代碼
scanf("%d%d%d",&a,&b,&c);
printf("%d,%d,%d\n",a,b,c);
}
輸出:
輸入:2<enter>d<enter>
輸出:2輸入成功,d輸入不匹配,當(dāng)不匹配時(shí)結(jié)束scanf()
※思考與總結(jié)※
scanf語(yǔ)句執(zhí)行時(shí),首先試圖從緩沖區(qū)中讀入一個(gè)%d類(lèi)型的數(shù)據(jù),如果和第一個(gè)參數(shù)匹配,則繼續(xù)從緩沖區(qū)中讀取數(shù)據(jù)和第二個(gè)參數(shù)進(jìn)行匹配,依次進(jìn)行下去,直到匹配完所有的參數(shù);如果其中有一個(gè)參數(shù)不匹配,那就從這個(gè)地方跳出(第二個(gè)參數(shù)開(kāi)始不匹配就從第二個(gè)參數(shù)出跳出,第一個(gè)參數(shù)匹配有效),忽略這個(gè)scanf后面所有的參數(shù),結(jié)束scanf( )函數(shù),繼續(xù)向下執(zhí)行下一條語(yǔ)句。
4)scanf( )存在緩存區(qū)
#include <stdio.h>
int main()
{
int a[3];
int i;
for(i = 0; i < 3; i++)
{
printf("Please input number:\n");
scanf("%d",&a[i]);
}
for(i = 0; i < 3; i++)
{
printf("%d,",a[i]);
}
printf("\n");
return 0;
}
輸入:2<space>3<spacer>4<space>
輸出:
※思考與總結(jié)※
發(fā)現(xiàn),還沒(méi)有等輸入第二次,程序已經(jīng)結(jié)束了。當(dāng)一次性輸入‘2 3 4’時(shí),會(huì)存儲(chǔ)到緩存區(qū)中,下一次輸入直接在緩存區(qū)中取,若參數(shù)匹配,輸入成功,若不匹配同上scanf( )結(jié)束。即此時(shí):
for( )循環(huán)體內(nèi)的三次scanf(“%d”,&a[i])等價(jià) scanf(“%d%d%d”,&a[0],&a[1],&a[2]);
(2)scanf(“%d,%d,%d”,&a,&b,&c); / / %d與%d之間多了“,”
#include <stdio.h>
int main()
{
int a,b,c;
scanf("%d,%d,%d",&a,&b,&c);
printf("%d,%d,%d\n",a,b,c);
}
輸入:
a)1, 2,3
b)1,<space>2,<space><space>3
c)1<space>,2,3
輸出:
a)
b)
c)
※思考與總結(jié)※
scanf()的格式控制串可以使用其它非空白字符例如a)、b)沒(méi)有問(wèn)題,但在輸入時(shí)必須輸入這些字符并且位置與格式控制串相一致,如上c)例子,“,”號(hào)必須緊跟在輸入整數(shù)后,不能被空白字符隔開(kāi)。
3.2 輸入字符串(%s)
#include <stdio.h>
int main()
{
char a[100];
scanf("%s",a);
printf("%s\n",a);
return 0;
}
輸入:hello<space>world
輸出:hello
※思考與總結(jié)※
如果使用%s轉(zhuǎn)換說(shuō)明,scanf( )會(huì)讀取除空白符以外的所有字符,scanf( )跳過(guò)空白符開(kāi)始讀第一個(gè)非空白符,并保存非空白符直到再次遇到空白符。這就意味著scanf( )根據(jù)%s轉(zhuǎn)換說(shuō)明讀取一個(gè)單詞,即不包含空白字符的字符串。后要注意:scanf( )將字符串放入指定數(shù)組中時(shí),它會(huì)在字符序列的末尾加上’\0’。
那么world哪里去了呢?在緩存區(qū)中,修改程序如下:
#include <stdio.h>
int main()
{
char a[100];
printf("Please input string:\n");
scanf("%s",a);
printf("print:%s\n",a);
scanf("%s",a);
printf("print:%s\n",a);
return 0;
}
輸入:hello<space>world
輸出:
3.3 輸入字符(%c)
#include <stdio.h>
int main()
{
char ch1,ch2;
scanf("%c%c",&ch1,&ch2);
printf("ch1 : %c ch2 : %c\n",ch1,ch2);
return 0;
}
輸入:a<enter>b<enter>//輸入a<enter>后程序已經(jīng)結(jié)束
輸出:
※思考與總結(jié)※
ch2里存了什么字符呢?我們選擇%d的格式將ch1和ch2以%d格式打印即:printf("ch1 : %d ch2 : %d\n",ch1,ch2);
輸出:
通過(guò)man ascii查詢(xún)得到
10對(duì)應(yīng)的是’\n’換行符,13對(duì)應(yīng)的是’\r’回車(chē),每當(dāng)敲擊<enter>鍵,’\r’被輸入緩存區(qū),’\n’被“錯(cuò)誤”的賦給了ch2(暫且這么認(rèn)為)。
可以這樣解決問(wèn)題
#include <stdio.h>
int main()
{
char ch1,ch2;
scanf("%c",&ch1);
getchar(); //字符輸入函數(shù),吸收敲擊回車(chē)產(chǎn)生的’\n’
scanf("%c",&ch2);
printf("ch1 : %d ch2 : %d\n",ch1,ch2);
return 0;
}