 關(guan)于scanf( )函數使用
							時間:2018-09-29      來源:未知
							關(guan)于scanf( )函數使用
							時間:2018-09-29      來源:未知 
							1.scanf( )函數介(jie)紹(shao)
C庫中(zhong)包含了多個(ge)輸入(ru)函數,scanf( )是通用的(de)一個(ge),因為(wei)他(ta)可以讀取不同格(ge)式(shi)的(de)數據。如果想(xiang)輸入(ru)整數100,就要(yao)鍵入(ru)字(zi)符1、0、0,那么scanf()要(yao)做(zuo)的(de)就是將字(zi)符依次轉(zhuan)換成(cheng)數值。
頭文件:#include<stdio.h>
用法:
int scanf(const char *format, ...);
其調用格式(shi)為: scanf("<格式(shi)化字(zi)符串>",<地址表>);
例如:scanf(“%d%d”,&a,&b); //a和b為(wei)int類(lei)型(xing)變(bian)量
%d // 轉換說明,表明目標(biao)數據類型為int型
功能:
scanf()函(han)數(shu)是(shi)格式化輸入(ru)(ru)函(han)數(shu),它從鍵盤(標準輸入(ru)(ru)設備)輸入(ru)(ru),讀取輸入(ru)(ru)字(zi)符(fu),根(gen)據格式字(zi)符(fu)串(chuan)表明(ming)字(zi)符(fu)輸入(ru)(ru)流的(de)目標數(shu)據類型。
返回值:
scanf()函數(shu)返(fan)回成功賦值的數(shu)據項(xiang)數(shu),出錯時(shi)則返(fan)回EOF。
2.轉換說(shuo)明
什么(me)是轉換(huan)說(shuo)(shuo)明呢(ni)?既然scanf( )是標(biao)準格式輸(shu)入(ru)函(han)數(shu),那么(me)輸(shu)入(ru)的(de)數(shu)據就要(yao)存儲(chu)到目(mu)標(biao)變量中(zhong),而目(mu)標(biao)變量又會有(you)很多種(zhong)類(lei)型(xing),例如int、char、float等,scanf( )如何區分呢(ni)?于是,轉換(huan)說(shuo)(shuo)明出現了,他指明了scanf( )把輸(shu)入(ru)解釋成什么(me)數(shu)據類(lei)型(xing),存儲(chu)到相(xiang)對應的(de)目(mu)標(biao)變量中(zhong)。就像一家啤(pi)酒(jiu)(jiu)廠商,生產出的(de)啤(pi)酒(jiu)(jiu)是雪(xue)花啤(pi)酒(jiu)(jiu),就要(yao)放(fang)入(ru)雪(xue)花啤(pi)酒(jiu)(jiu)瓶(ping)(ping)中(zhong),淡爽啤(pi)酒(jiu)(jiu)就要(yao)放(fang)入(ru)淡爽啤(pi)酒(jiu)(jiu)瓶(ping)(ping)中(zhong),同理(li)轉換(huan)說(shuo)(shuo)明就起到了我(wo)們輸(shu)入(ru)的(de)數(shu)據要(yao)解釋成與目(mu)標(biao)變量相(xiang)對應的(de)數(shu)據類(lei)型(xing)。
ANSI中scanf( )的轉換(huan)說明
轉換說明 含義
%c 把輸入解釋成字符
%d 把輸(shu)入解釋成有符號十進(jin)制整數
%e、%f、%g、%a 把輸入解釋成浮點數
%E、%F/、%G、%A 把輸入解釋成浮點數
%i 把輸入(ru)解釋(shi)成有符號的十進制(zhi)整數
%o 把輸入解釋(shi)成(cheng)有符號的八進制整數
%p 把輸入解釋成指針
%s 把輸入解釋成字符串
%u 把輸入(ru)解釋成無符號(hao)十(shi)進制整數
%x、%X 把輸入(ru)解釋成有符(fu)號十六進(jin)制整數
3.scanf函數(shu)用法(fa)
3.1 輸入整數(%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) 輸入(ru):2<enter>3<enter>4<enter>
輸(shu)出:2,3,4
2) 輸入:<space> 2 <space> 3 <space> 4 <space>
輸出(chu):2,3,4
※思考與總結(jie)※
scanf函數每(mei)次(ci)讀(du)(du)取(qu)(qu)一(yi)(yi)個字(zi)(zi)符(fu)(fu)(fu),跳過所有空(kong)白字(zi)(zi)符(fu)(fu)(fu),直至(zhi)遇到(dao)第一(yi)(yi)個非空(kong)白字(zi)(zi)符(fu)(fu)(fu)才(cai)開始讀(du)(du)取(qu)(qu),因為要讀(du)(du)取(qu)(qu)整數,所以希望(wang)發現(xian)一(yi)(yi)個數字(zi)(zi)字(zi)(zi)符(fu)(fu)(fu)或者一(yi)(yi)個符(fu)(fu)(fu)號(+或-),如何找(zhao)到(dao)一(yi)(yi)個數字(zi)(zi)或符(fu)(fu)(fu)號,便保(bao)存字(zi)(zi)符(fu)(fu)(fu),并讀(du)(du)取(qu)(qu)下一(yi)(yi)個字(zi)(zi)符(fu)(fu)(fu),直至(zhi)遇到(dao)非數字(zi)(zi)字(zi)(zi)符(fu)(fu)(fu)。如果遇到(dao)非數字(zi)(zi)字(zi)(zi)符(fu)(fu)(fu),便認為讀(du)(du)到(dao)了末尾,然后scanf把非數字(zi)(zi)字(zi)(zi)符(fu)(fu)(fu)放(fang)回輸(shu)入(ru)。這就意味著程序在(zai)下一(yi)(yi)次(ci)讀(du)(du)取(qu)(qu)輸(shu)入(ru)時,首先(xian)讀(du)(du)到(dao)的是(shi)上一(yi)(yi)次(ci)讀(du)(du)取(qu)(qu)丟(diu)棄的非數字(zi)(zi)字(zi)(zi)符(fu)(fu)(fu)。
空(kong)(kong)白(bai)(bai)字符會使scanf()函數在讀操作(zuo)中略去輸入中的一個或多個空(kong)(kong)白(bai)(bai)字符,空(kong)(kong)白(bai)(bai)符可(ke)以是space,tab,newline等(deng)等(deng),直(zhi)到第一個非空(kong)(kong)白(bai)(bai)符出現為止(zhi)。
<tab> 2 <tab> 3 <tab> 4 <tab> // 輸出同(tong)上,<tab>為空白字符
3) 輸入:c<enter>
#include <stdio.h>
int main()
{
int a,b,c;
printf("%d,%d,%d\n",a,b,c);//增加一行(xing)代(dai)碼
scanf("%d%d%d",&a,&b,&c);
printf("%d,%d,%d\n",a,b,c);
}
輸出:
  
輸入:2<enter>d<enter>
輸(shu)出:2輸(shu)入成(cheng)功,d輸(shu)入不匹配(pei),當不匹配(pei)時結束scanf()
※思考(kao)與(yu)總(zong)結※
scanf語句執行時,首先試圖(tu)從緩(huan)沖區(qu)(qu)中(zhong)讀入一(yi)個(ge)%d類型的(de)數據,如(ru)果(guo)(guo)和第(di)(di)一(yi)個(ge)參(can)(can)(can)數匹(pi)配,則繼續(xu)從緩(huan)沖區(qu)(qu)中(zhong)讀取數據和第(di)(di)二(er)個(ge)參(can)(can)(can)數進(jin)行匹(pi)配,依次進(jin)行下去,直到匹(pi)配完(wan)所有的(de)參(can)(can)(can)數;如(ru)果(guo)(guo)其(qi)中(zhong)有一(yi)個(ge)參(can)(can)(can)數不匹(pi)配,那就(jiu)從這個(ge)地方跳出(chu)(第(di)(di)二(er)個(ge)參(can)(can)(can)數開(kai)始不匹(pi)配就(jiu)從第(di)(di)二(er)個(ge)參(can)(can)(can)數出(chu)跳出(chu),第(di)(di)一(yi)個(ge)參(can)(can)(can)數匹(pi)配有效),忽略(lve)這個(ge)scanf后面所有的(de)參(can)(can)(can)數,結束(shu)scanf( )函數,繼續(xu)向下執行下一(yi)條(tiao)語句。
4)scanf( )存在緩存區
#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;
}
輸(shu)入:2<space>3<spacer>4<space>
輸出:
  
※思考(kao)與總(zong)結※
發現(xian),還沒有等輸入第二(er)次,程(cheng)序已(yi)經結束了。當一次性(xing)輸入‘2 3 4’時,會存儲到緩存區中(zhong),下一次輸入直(zhi)接在(zai)緩存區中(zhong)取,若參數匹配(pei),輸入成功(gong),若不匹配(pei)同上(shang)scanf( )結束。即此時:
for( )循環(huan)體內的(de)三(san)次scanf(“%d”,&a[i])等價 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)
 
※思考與(yu)總結(jie)※
scanf()的格式控制(zhi)串可以使用其它非空白字符(fu)例如a)、b)沒(mei)有問題,但在(zai)輸(shu)入時必(bi)須輸(shu)入這些(xie)字符(fu)并且位置與格式控制(zhi)串相一致,如上c)例子(zi),“,”號(hao)必(bi)須緊跟(gen)在(zai)輸(shu)入整數后,不能(neng)被(bei)空白字符(fu)隔開。
3.2 輸入(ru)字符串(%s)
#include <stdio.h>
int main()
{
char a[100];
scanf("%s",a);
printf("%s\n",a);
return 0;
}
輸(shu)入:hello<space>world
輸出(chu):hello
※思(si)考(kao)與總結※
如(ru)果使用%s轉換說(shuo)明(ming)(ming),scanf( )會讀(du)(du)取除(chu)空白符(fu)(fu)(fu)以外的(de)所有字(zi)(zi)符(fu)(fu)(fu),scanf( )跳過空白符(fu)(fu)(fu)開始讀(du)(du)第一(yi)個非(fei)空白符(fu)(fu)(fu),并保存非(fei)空白符(fu)(fu)(fu)直(zhi)到再次(ci)遇到空白符(fu)(fu)(fu)。這就意(yi)味著scanf( )根據%s轉換說(shuo)明(ming)(ming)讀(du)(du)取一(yi)個單(dan)詞,即不(bu)包含空白字(zi)(zi)符(fu)(fu)(fu)的(de)字(zi)(zi)符(fu)(fu)(fu)串。后要注意(yi):scanf( )將字(zi)(zi)符(fu)(fu)(fu)串放入指定數組中時,它會在字(zi)(zi)符(fu)(fu)(fu)序列的(de)末尾加上’\0’。
那么world哪里去(qu)了呢?在(zai)緩存(cun)區(qu)中,修改程序如下:
#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;
}
輸(shu)入:hello<space>world
輸出:
  
3.3 輸入字(zi)符(%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>后程序已(yi)經結束
輸出:
  
※思考與總結※
ch2里存(cun)了什(shen)么字符呢?我們選(xuan)擇%d的(de)格式將ch1和ch2以%d格式打印即(ji):printf("ch1 : %d ch2 : %d\n",ch1,ch2);
輸出:
  
通過man ascii查詢(xun)得(de)到
  
10對應的是’\n’換行符(fu),13對應的是’\r’回車,每當敲擊<enter>鍵(jian),’\r’被(bei)輸入緩存區,’\n’被(bei)“錯誤”的賦給了ch2(暫且這么認為(wei))。
可(ke)以這樣(yang)解(jie)決(jue)問題
#include <stdio.h>
int main()
{
char ch1,ch2;
scanf("%c",&ch1);
getchar(); //字(zi)符輸入函數(shu),吸(xi)收敲擊回車產生(sheng)的’\n’
scanf("%c",&ch2);
printf("ch1 : %d ch2 : %d\n",ch1,ch2);
return 0;
}

