溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

scanf函數(shù)在C語言中的作用有哪些

發(fā)布時間:2020-12-10 13:40:22 來源:億速云 閱讀:4826 作者:Leah 欄目:開發(fā)技術(shù)

scanf函數(shù)在C語言中的作用有哪些?相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

1、scanf的返回值

scanf通常返回的是成功賦值(從標(biāo)準(zhǔn)輸入設(shè)備賦值到參數(shù)列表所指定的內(nèi)存區(qū)域)的數(shù)據(jù)項(xiàng)數(shù),如果出錯或是遇到end of file(注意,如果想從鍵盤輸入EOF,在windows的DOS窗口用Ctrl+Z 或F6;在UNIX系統(tǒng)上,用CTRL+D。),則返回EOF,比如:

scanf("%d%d", &x, &y);

如果x和y都被成功讀入,那么scanf的返回值就是2;

如果只有x被成功讀入,返回值為1;

如果x和y都未被成功讀入,返回值為0;

如果遇到錯誤或遇到end of file,返回值為EOF。

2、scanf的處理機(jī)制

scanf以刪除的方式從緩沖區(qū)讀入數(shù)據(jù)(來自標(biāo)準(zhǔn)輸入設(shè)備的數(shù)據(jù)存儲在緩沖區(qū)),也就是說,scanf從緩沖區(qū)讀入一個數(shù)據(jù)項(xiàng),該數(shù)據(jù)項(xiàng)在緩沖區(qū)中就被清除掉了。

而如果scanf需要讀取一個數(shù)據(jù)項(xiàng),返現(xiàn)緩沖區(qū)當(dāng)前是空的,那么程序就會在scanf代碼處阻塞,等待用戶輸入,scanf函數(shù)接收到相應(yīng)的數(shù)據(jù)項(xiàng)之后,在緩沖區(qū)中將這一數(shù)據(jù)項(xiàng)清除,scanf函數(shù)返回,程序繼續(xù)執(zhí)行。

3、scanf對不同類型輸入的處理方式

首先,要清除一個概念:空白字符(white space)。一般,程序中所指的空白字符是指空格(space),回車(enter)和指標(biāo)符(table)。

3.1 整數(shù)%d

對于整型數(shù)據(jù)的輸入,也就是說"%d"類型的輸入,scanf默認(rèn)的分割符是所有的空白字符(空格,回車和指標(biāo)符都行)。

也就是說如果一個scanf函數(shù)中出現(xiàn)scanf("%d%d",&a,&b),那么用任何一個空白字符來分隔兩個整數(shù)a,b的值,變量a,b都可以接收到正確的輸入。

另外,要注意的是,scanf對于數(shù)字輸入,會忽略輸入數(shù)據(jù)項(xiàng)前面的空白字符。下面是例1:

Code:
#include<stdio.h>
int main()
{
 int a,b;
 printf("Input the value of a and b:");
 while(scanf("%d%d",&a,&b)!=EOF)
 {
 printf("a=%d,b=%d\n",a,b);
 printf("Input the value of a and b:");
 }
 return 0;
}
Output:
Input the value of a and b:123 456
a=123,b=456
Input the value of a and b:123 456
a=123,b=456
Input the value of a and b:123
456
a=123,b=456
Input the value of a and b:
123 456
a=123,b=456
Input the value of a and b:  123 456
a=123,b=456
Input the value of a and b: 123 456
a=123,b=456
Input the value of a and b:^Z
Press any key to continue

3.2 字符串%s

scanf對于字符串輸入的處理和對整數(shù)類似,會忽略前導(dǎo)的空白字符,而且默認(rèn)的分隔符是所有的空白字符。但是,要注意的是,由于C語言中,沒有string類型,都是用char型數(shù)組來表示。

因此,scanf會為每一個輸入的字符串最后加一個‘\0'。下面是一個例子,可以看出scanf這貨的邊界控制還是要小心。

如下例2。

#include<stdio.h>
int main()
{
 char a[5],b[5];
 int i;
 printf("Input the value of a and b:");
 while(scanf("%s%s",a,b)!=EOF)
 {
 printf("a=%s,b=%s\n",a,b);
 for(i=0;i<5;i++)
 printf("%d:(%c) ",a[i],a[i]);
 printf("\n");
 for(i=0;i<5;i++)
 printf("%d:(%c) ",b[i],b[i]);
 printf("\n");
 printf("Input the value of a and b:");
 }
 return 0;
}

運(yùn)行結(jié)果:

scanf函數(shù)在C語言中的作用有哪些

3.3 字符%c

scanf在處理對字符數(shù)據(jù)的輸入時,既不會忽略前導(dǎo)空白字符,默認(rèn)也沒有任何分隔字符。所有的字符,包括空白字符都會被當(dāng)成輸入字符。

下面是例3。

#include<stdio.h>
int main()
{
 char a ,b ;
 printf("Input the value of a and b:");
 while(scanf("%c%c",&a,&b)!=EOF)
 {
 printf("a=%c,b=%c\n",a,b);
 printf("Input the value of a and b:");
 }
 return 0;
}

運(yùn)行結(jié)果:

scanf函數(shù)在C語言中的作用有哪些

可以看出,在對字符數(shù)據(jù)輸入的時候,由于緩沖區(qū)中有回車空格等數(shù)據(jù),會導(dǎo)致輸入數(shù)據(jù)比較詭異,為了解決這個問題,有以下方法:

(1) 清空緩沖區(qū)

在微軟系統(tǒng)中,有一個名為fflush(stdin)的函數(shù),可以用來清空緩沖區(qū),

如下例4。

#include<stdio.h>
int main()
{
 char a ,b ;
 printf("Input the value of a and b:");
 while(scanf("%c%c",&a,&b)!=EOF)
 {
 printf("a=%c,b=%c\n",a,b);
 fflush(stdin);
 printf("Input the value of a and b:");
 }
 return 0;
}

運(yùn)行結(jié)果:

scanf函數(shù)在C語言中的作用有哪些

(2)將緩沖區(qū)的數(shù)據(jù)讀出來

有的編譯系統(tǒng)并沒有定義stdin的fflush操作,這個時候,可以把緩沖區(qū)中的數(shù)據(jù)讀出來,有如下幾種可行的方法:

1) getchar()

將例4中的fflush(stdin);語句換成

char c;

while((c=getchar())!='\n'&&c!=EOF);

運(yùn)行效果和上面的相同。

2) gets()

char* gets(char* buffer)從stdin流中讀取字符串,直至接受到換行符或EOF時停止,并將讀取的結(jié)果存放在buffer指針?biāo)赶虻淖址麛?shù)組中。換行符不作為讀取串的內(nèi)容,讀取的換行符被轉(zhuǎn)換為null值,并由此來結(jié)束字符串。

讀入成功,返回與參數(shù)buffer相同的指針;讀入過程中遇到EOF(End-of-File)或發(fā)生錯誤,返回NULL指針。

所以在遇到返回值為NULL的情況,要用ferror或feof函數(shù)檢查是發(fā)生錯誤還是遇到EOF。

要注意的是gets函數(shù)可以無限讀取,不會判斷上限,所以應(yīng)該確保buffer的空間足夠大,以便在執(zhí)行讀操作時不發(fā)生溢出。如果溢出,多出來的字符將被寫入到堆棧中,這就覆蓋了堆棧原先的內(nèi)容,破壞一個或多個不相關(guān)變量的值。

將例4中的fflush(stdin);語句換成

char c[10];

gets(c);

運(yùn)行效果也和上面的相同。

4、在stackoverflow上看到的一個問題

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *method1(void)
{
 static char a[4];
 scanf ("%s\n", a);
 return a;
}
 
int main(void)
{
 char *h = method1();
 printf ("%s\n", h);
 return 0;
}

運(yùn)行結(jié)果:

ab
cd
ab
Press any key to continue

可以發(fā)現(xiàn),輸如兩次之后才會輸出。這個現(xiàn)象比較詭異,原因如下:

White space (such as blanks, tabs, or newlines) in the format string match any amount of white space, including none, in the input. Everything else matches only itself.

Thus with scanf ("%s\n", a) it will scan for a string followed by optional white space. Since after the first newline more whitespace may follow, scanf is not done after the first newline and looks what's next. You will notice that you can enter any number of newlines (or tabs or spaces) and scanf will still wait for more.

However, when you enter the second string, the sequence of whitespace is delimited and scanning stops.

看完上述內(nèi)容,你們掌握scanf函數(shù)在C語言中的作用有哪些的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI