關于scanf( )函數使用
時間:2018-09-29 來源:未知
1.scanf( )函數介紹
C庫中包含了多個輸入函數,scanf( )是通用的一個,因為他可以讀取不同格式的數據。如果想輸入整數100,就要鍵入字符1、0、0,那么scanf()要做的就是將字符依次轉換成數值。
頭文件:#include<stdio.h>
用法:
int scanf(const char *format, ...);
其調用格式為: scanf("<格式化字符串>",<地址表>);
例如:scanf(“%d%d”,&a,&b); //a和b為int類型變量
%d // 轉換說明,表明目標數據類型為int型
功能:
scanf()函數是格式化輸入函數,它從鍵盤(標準輸入設備)輸入,讀取輸入字符,根據格式字符串表明字符輸入流的目標數據類型。
返回值:
scanf()函數返回成功賦值的數據項數,出錯時則返回EOF。
2.轉換說明
什么是轉換說明呢?既然scanf( )是標準格式輸入函數,那么輸入的數據就要存儲到目標變量中,而目標變量又會有很多種類型,例如int、char、float等,scanf( )如何區分呢?于是,轉換說明出現了,他指明了scanf( )把輸入解釋成什么數據類型,存儲到相對應的目標變量中。就像一家啤酒廠商,生產出的啤酒是雪花啤酒,就要放入雪花啤酒瓶中,淡爽啤酒就要放入淡爽啤酒瓶中,同理轉換說明就起到了我們輸入的數據要解釋成與目標變量相對應的數據類型。
ANSI中scanf( )的轉換說明
轉換說明 含義
%c 把輸入解釋成字符
%d 把輸入解釋成有符號十進制整數
%e、%f、%g、%a 把輸入解釋成浮點數
%E、%F/、%G、%A 把輸入解釋成浮點數
%i 把輸入解釋成有符號的十進制整數
%o 把輸入解釋成有符號的八進制整數
%p 把輸入解釋成指針
%s 把輸入解釋成字符串
%u 把輸入解釋成無符號十進制整數
%x、%X 把輸入解釋成有符號十六進制整數
3.scanf函數用法
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) 輸入:2<enter>3<enter>4<enter>
輸出:2,3,4
2) 輸入:<space> 2 <space> 3 <space> 4 <space>
輸出:2,3,4
※思考與總結※
scanf函數每次讀取一個字符,跳過所有空白字符,直至遇到第一個非空白字符才開始讀取,因為要讀取整數,所以希望發現一個數字字符或者一個符號(+或-),如何找到一個數字或符號,便保存字符,并讀取下一個字符,直至遇到非數字字符。如果遇到非數字字符,便認為讀到了末尾,然后scanf把非數字字符放回輸入。這就意味著程序在下一次讀取輸入時,首先讀到的是上一次讀取丟棄的非數字字符。
空白字符會使scanf()函數在讀操作中略去輸入中的一個或多個空白字符,空白符可以是space,tab,newline等等,直到第一個非空白符出現為止。
<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輸入不匹配,當不匹配時結束scanf()
※思考與總結※
scanf語句執行時,首先試圖從緩沖區中讀入一個%d類型的數據,如果和第一個參數匹配,則繼續從緩沖區中讀取數據和第二個參數進行匹配,依次進行下去,直到匹配完所有的參數;如果其中有一個參數不匹配,那就從這個地方跳出(第二個參數開始不匹配就從第二個參數出跳出,第一個參數匹配有效),忽略這個scanf后面所有的參數,結束scanf( )函數,繼續向下執行下一條語句。
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;
}
輸入:2<space>3<spacer>4<space>
輸出:

※思考與總結※
發現,還沒有等輸入第二次,程序已經結束了。當一次性輸入‘2 3 4’時,會存儲到緩存區中,下一次輸入直接在緩存區中取,若參數匹配,輸入成功,若不匹配同上scanf( )結束。即此時:
for( )循環體內的三次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)

※思考與總結※
scanf()的格式控制串可以使用其它非空白字符例如a)、b)沒有問題,但在輸入時必須輸入這些字符并且位置與格式控制串相一致,如上c)例子,“,”號必須緊跟在輸入整數后,不能被空白字符隔開。
3.2 輸入字符串(%s)
#include <stdio.h>
int main()
{
char a[100];
scanf("%s",a);
printf("%s\n",a);
return 0;
}
輸入:hello<space>world
輸出:hello
※思考與總結※
如果使用%s轉換說明,scanf( )會讀取除空白符以外的所有字符,scanf( )跳過空白符開始讀第一個非空白符,并保存非空白符直到再次遇到空白符。這就意味著scanf( )根據%s轉換說明讀取一個單詞,即不包含空白字符的字符串。后要注意:scanf( )將字符串放入指定數組中時,它會在字符序列的末尾加上’\0’。
那么world哪里去了呢?在緩存區中,修改程序如下:
#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>后程序已經結束
輸出:

※思考與總結※
ch2里存了什么字符呢?我們選擇%d的格式將ch1和ch2以%d格式打印即:printf("ch1 : %d ch2 : %d\n",ch1,ch2);
輸出:

通過man ascii查詢得到

10對應的是’\n’換行符,13對應的是’\r’回車,每當敲擊<enter>鍵,’\r’被輸入緩存區,’\n’被“錯誤”的賦給了ch2(暫且這么認為)。
可以這樣解決問題
#include <stdio.h>
int main()
{
char ch1,ch2;
scanf("%c",&ch1);
getchar(); //字符輸入函數,吸收敲擊回車產生的’\n’
scanf("%c",&ch2);
printf("ch1 : %d ch2 : %d\n",ch1,ch2);
return 0;
}

