您好,登錄后才能下訂單哦!
scanf函數在C語言中的作用有哪些?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
1、scanf的返回值
scanf通常返回的是成功賦值(從標準輸入設備賦值到參數列表所指定的內存區域)的數據項數,如果出錯或是遇到end of file(注意,如果想從鍵盤輸入EOF,在windows的DOS窗口用Ctrl+Z 或F6;在UNIX系統上,用CTRL+D。),則返回EOF,比如:
scanf("%d%d", &x, &y);
如果x和y都被成功讀入,那么scanf的返回值就是2;
如果只有x被成功讀入,返回值為1;
如果x和y都未被成功讀入,返回值為0;
如果遇到錯誤或遇到end of file,返回值為EOF。
scanf以刪除的方式從緩沖區讀入數據(來自標準輸入設備的數據存儲在緩沖區),也就是說,scanf從緩沖區讀入一個數據項,該數據項在緩沖區中就被清除掉了。
而如果scanf需要讀取一個數據項,返現緩沖區當前是空的,那么程序就會在scanf代碼處阻塞,等待用戶輸入,scanf函數接收到相應的數據項之后,在緩沖區中將這一數據項清除,scanf函數返回,程序繼續執行。
首先,要清除一個概念:空白字符(white space)。一般,程序中所指的空白字符是指空格(space),回車(enter)和指標符(table)。
3.1 整數%d
對于整型數據的輸入,也就是說"%d"類型的輸入,scanf默認的分割符是所有的空白字符(空格,回車和指標符都行)。
也就是說如果一個scanf函數中出現scanf("%d%d",&a,&b),那么用任何一個空白字符來分隔兩個整數a,b的值,變量a,b都可以接收到正確的輸入。
另外,要注意的是,scanf對于數字輸入,會忽略輸入數據項前面的空白字符。下面是例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對于字符串輸入的處理和對整數類似,會忽略前導的空白字符,而且默認的分隔符是所有的空白字符。但是,要注意的是,由于C語言中,沒有string類型,都是用char型數組來表示。
因此,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; }
運行結果:
3.3 字符%c
scanf在處理對字符數據的輸入時,既不會忽略前導空白字符,默認也沒有任何分隔字符。所有的字符,包括空白字符都會被當成輸入字符。
下面是例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; }
運行結果:
可以看出,在對字符數據輸入的時候,由于緩沖區中有回車空格等數據,會導致輸入數據比較詭異,為了解決這個問題,有以下方法:
(1) 清空緩沖區
在微軟系統中,有一個名為fflush(stdin)的函數,可以用來清空緩沖區,
如下例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; }
運行結果:
(2)將緩沖區的數據讀出來
有的編譯系統并沒有定義stdin的fflush操作,這個時候,可以把緩沖區中的數據讀出來,有如下幾種可行的方法:
1) getchar()
將例4中的fflush(stdin);語句換成
char c;
while((c=getchar())!='\n'&&c!=EOF);
運行效果和上面的相同。
2) gets()
char* gets(char* buffer)從stdin流中讀取字符串,直至接受到換行符或EOF時停止,并將讀取的結果存放在buffer指針所指向的字符數組中。換行符不作為讀取串的內容,讀取的換行符被轉換為null值,并由此來結束字符串。
讀入成功,返回與參數buffer相同的指針;讀入過程中遇到EOF(End-of-File)或發生錯誤,返回NULL指針。
所以在遇到返回值為NULL的情況,要用ferror或feof函數檢查是發生錯誤還是遇到EOF。
要注意的是gets函數可以無限讀取,不會判斷上限,所以應該確保buffer的空間足夠大,以便在執行讀操作時不發生溢出。如果溢出,多出來的字符將被寫入到堆棧中,這就覆蓋了堆棧原先的內容,破壞一個或多個不相關變量的值。
將例4中的fflush(stdin);語句換成
char c[10];
gets(c);
運行效果也和上面的相同。
#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; }
運行結果:
ab cd ab Press any key to continue
可以發現,輸如兩次之后才會輸出。這個現象比較詭異,原因如下:
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.
看完上述內容,你們掌握scanf函數在C語言中的作用有哪些的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。