scanf()函式的用法和實踐 (轉)
scanf()的用法和實踐:namespace prefix = o ns = "urn:schemas--com::office" />
daizh
摘要:
本文闡述了基於ANSI,Win 95,Win NT上的 C/C++語言中scanf()函式的用法,以及在實際使用中常見錯誤及對策。
關鍵詞:
scanf()
一、 序言
在CSDN論壇的C/C++版塊,我時常見到“對於scanf()函式的用法、及出現的各種錯誤而迷惑”的帖子,萌發了我寫這篇文章的念頭。文中結合自身在學習和中對它的認識和體會,以具體示例闡述問題,目的在於使得初學者能夠正確使用scanf()函式,少走不必要的彎路。
二、 scanf()函式的用法
scanf()函式是格式化輸入函式,它從標準輸入裝置(鍵盤) 讀取輸入的資訊。
其格式為: scanf("",);
格式化字串包括以下三類不同的字元;
1、 格式化說明符:
格式化說明符與printf()函式中的格式說明符基本相同。但和printf()函式中格式字串的用法有一些小區別。我們來看下面這個表。
格式字元
說明
%d
從鍵盤輸入十進位制整數
%o
從鍵盤輸入八進位制整數
%x
從鍵盤輸入十六進位制整數
%c
從鍵盤輸入一個字元
%s
從鍵盤輸入一個字串
%f
從鍵盤輸入一個實數
%e
與%f的作用相同
附加格式說明字元表
字元
說明
L
輸入"長"資料
H
輸入"短"資料
M
指定輸入資料所佔寬度
*
空讀一個資料
2、 空白字元: 空白字元會使scanf()函式在讀操作中略去輸入中的一個或多個空白字元。
3、 非空白字元: 一個非空白字元會使scanf()函式在讀入時剔除掉與這個非空白字元相同的字元。
地址表是需要讀入的所有變數的地址,而不是變數本身。這與printf()函式完全不同,要特別注意。各個變數的地址之間同","分開。
例如:
#include
void main()
{
int i, j;
printf("i, j=? ");
scanf("%d, %d", &i, &j);
}
上例中的scanf()函式先讀一個整型數,然後把接著輸入的逗號剔除掉,最後讀入另一個整型數。如果","這一特定字元沒有找到,scanf()函式就終止。若引數之間的分隔符為空格,則引數之間必須輸入一個或多個空格。
說明:
(1) 對於字串陣列或字串指標變數,由於陣列名和指標變數名本身就是地址,因此使用scanf()函式時,不需要在它們前面加上"&"運算子。
例如:
#include
void main()
{
char *p, str[20];
p = new char[20];
scanf("%s", p); /*從健盤輸入字串*/
scanf("%s", str);
printf("%s ", p); /*向螢幕輸出字串*/
printf("%s ", str);
}
(2) 可以在格式化字串中的"%"各格式化規定符之間加入一個整數,表示任何讀操作中的最大位數。
如上例中若規定只能輸入10字元給字串指標p,則第一條scanf() 函式語句變為:scanf("%10s", p);
執行時一旦輸入字元個數大於10,p就不再繼續讀入,而後面的一個讀入函式即scanf("%s", str)就會從第11個字元開始讀入。
(3) scanf()函式中沒有精度控制。
如: scanf("%5.2f",&a); 是的。不能企圖用此語句輸入小數為2位的實數。
(4) scanf中要求給出變數地址,如給出變數名則會出錯
如 scanf("%d",a);是非法的,應改為scnaf("%d",&a);才是合法的。
(5) 在輸入多個數值資料時,若格式控制串中沒有非格式字元作輸入資料之間的間隔則可用空格,TAB或回車作間隔。
C編譯在碰到空格,TAB,回車或非法資料(如對“%d”輸入“12A”時,A即為非法資料)時即認為該資料結束。
(6) 在輸入字元資料(%c)時,若格式控制串中無非格式字元,則認為所有輸入的字元均為有效字元。
例如:scanf("%c%c%c",&a,&b,&c);
輸入為:
d e f
則把'd'賦予a, ' (空格)'賦予b,'e'賦予c。因為%c 只要求讀入一個字元,後面不需要用空格作為兩個字元的間隔,因此把' '作為下一個字元送給b。
只有當輸入為:def 時,才能把'd'賦於a,'e'賦予b,'f'賦予c。 如果在格式控制中加入空格作為間隔,
如 scanf ("%c %c %c",&a,&b,&c);則輸入時各資料之間可加空格。
我們用一些例子來說明一些規則:
#include
void main()
{
char a,b;
printf("input character a,b ");
scanf("%c%c",&a,&b); /*注意兩個%c之間沒有任何符號*/
printf("%c%c ",a,b);
}
由於scanf函式"%c%c"中沒有空格,輸入M N,結果輸出只有M。而輸入改為MN時則可輸出MN兩字元,見下面的輸入執行情況: input character a,b
MN (你輸入的值)
MN (螢幕上顯示的值)
#include
void main()
{
char a,b;
printf("input character a,b ");
scanf("%c %c",&a,&b); /*注意兩個%c之間有個空格*/
printf(" %c%c ",a,b);
}本例表示scanf格式控制串"%c %c"之間有空格時, 輸入的資料之間可以有空格間隔。
(7) 如果格式控制串中有非格式字元則輸入時也要輸入該非格式字元。
例如:
scanf("%d,%d,%d",&a,&b,&c); 其中用非格式符“ , ”作間隔符,故輸入時應為: 5,6,7 (與scanf 雙引號之間的格式必須一樣)
又如: scanf("a=%d,b=%d,c=%d",&a,&b,&c);
則輸入應為 a=5,b=6,c=7
如輸入的資料與輸出的型別不一致時,雖然編譯能夠透過,但結果將不正確。
#include
void main()
{
int a;
printf("input a number");
scanf("%d",&a);
printf("%ld",a);
}
由於輸入資料型別為整型, 而輸出語句的格式串中說明為長整型,因此輸出結果和輸入資料不符。輸出並不是輸入的值。
如將Scanf("%d",&a); 語句改為 scanf("%ld",&a);
輸入資料為長整型,輸入輸出資料才相等。
三、 常見錯誤及對策
問題1:
我初學C程式,所以提的問題很淺,希望您不要見笑。我自己編了一個程式,但執行的結果與我預期的不一樣。
#include
void main()
{
static int a[2][3]={{1,3,4},{7,9,6}};
int i,j,k;
for(k=1;k<=2;k++)
{printf("Please input num:");
scanf("%d %d",&i,&j);
if(i<2&&j<3)
printf("num=%d ",a[i][j]);
else printf("Input is error, ");
}
printf("programm is complete. ");
}
我想將第8行改為
scanf("i=%d j=%d",&i,&j);
則程式執行結果變成
please input num:i=1 j=2
num=6
num=6(我原本希望能重複第一行再讓我輸入)
Programm is complete.
為什麼第二次不能輸入?
答覆:
我使用Turbo C 2.0證實存在你說的問題。象scanf("i=%d j=%d",&i,&j);這樣的輸入方式比較特別,TC 2.0顯然在第一次輸入後沒有象正常情況一樣清楚輸入緩衝區,這樣第二次scanf時,程式並沒有讓你輸入而是直接讀入上次輸入的結果。如果你一定要這麼做,應該在scanf之前加上:
fflush(stdin);
這樣清楚掉鍵盤緩衝區。
問題2:
為什麼要把scanf("%c",varname)一定改成scanf(" %c")才可以正確接收字元?
答覆:
類似上題,在%c的前面必須有一個空格,否則會將你前面輸入別的值之後鍵入的回車符讀入該變數,造成死迴圈。當然,如果scanf("%c",&varname)是第一條讀入語句,就可以不需要空格。
問題3:(輸入變數時忘記加地址運算子“&”)
int a,b;
scanf("%d%d",a,b);
答覆:
這是不合法的。Scanf函式的作用是:按照a、b在的地址將a、b的值存進去。“&a”指a在記憶體中的地址。
問題4:(輸入資料的方式與要求不符)
①scanf("%d%d",&a,&b);
輸入時,不能用逗號作兩個資料間的分隔符,如下面輸入不合法:
3,4?
輸入資料時,在兩個資料之間以一個或多個空格間隔,也可用Enter鍵,跳格鍵tab。
②scanf("%d,%d",&a,&b);
C規定:如果在“格式控制”字串中除了格式說明以外還有其它字元,則在輸入資料時應輸入與這些字元相同的字元。下面輸入是合法的:
3,4?
此時不用逗號而用空格或其它字元是不對的。
3 4? 3:4?
又如:
scanf("a=%d,b=%d",&a,&b);
輸入應如以下形式:
a=3,b=4?
問題5:(輸入字元的格式與要求不一致)
在用“%c”格式輸入字元時,“空格字元”和“跳脫字元”都作為有效字元輸入。
scanf("%c%c%c",&c1,&c2,&c3);
如輸入a b c?
字元“a”送給c1,字元“ ”送給c2,字元“b”送給c3,因為%c只要求讀入一個字元,後面不需要用空格作為兩個字元的間隔。
問題6:(.輸入輸出的資料型別與所用格式說明符不一致)
例如,a已定義為整型,b定義為實型
a=3;b=4.5;
printf("%f%d ",a,b);
編譯時不給出出錯資訊,但執行結果將與原意不符。這種錯誤尤其需要注意。
問題7:(輸入資料時,企圖規定精度)
scanf("%7.2f",&a);
這樣做是不合法的,輸入資料時不能規定精度。
問題8:(在不應加地址運算子&的位置加了地址運算子)
scanf("%s",&str);
C語言編譯系統對陣列名的處理是:陣列名代表該陣列的起始地址,且scanf函式中的輸入項是字元陣列名,不必要再加地址符&。應改為:scanf("%s",str);
四、 結論
本文主要講述了C/C++中的scanf()函式的用法,重點闡述使用scanf()函式過程中出現的常見錯誤及對策。當然,文中某些解決方法,均可以採用其他函式和方法來更好地解決,但本文僅限討論scanf()函式本身。文中難免存在一些不足之處,歡迎讀者批評指正。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-962740/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- C語言中函式printf()和函式scanf()的用法C語言函式
- 關於scanf函式的問題函式
- ascii函式和substr函式的用法ASCII函式
- C++中scanf和printf系列函式簡介C++函式
- Golang:從fmt.Scanf函式想到的Golang函式
- 【轉】oracle的substr函式的用法Oracle函式
- StretchBlt函式和BitBlt函式的區別和用法函式
- async 函式的含義和用法函式
- Thunk 函式的含義和用法函式
- Excel isna函式的用法和例項Excel函式
- co 函式庫的含義和用法函式
- SQL中 CONVERT轉化函式的用法SQL函式
- SQL中CONVERT轉化函式的用法SQL函式
- C++的函式和模板函式 (轉)C++函式
- GetModuleFileName函式的用法函式
- createStyleSheet()函式的用法函式
- qsort函式的用法函式
- COALESCE函式的用法。函式
- Sanic response stream() 函式用法和示例函式
- Sanic response redirect() 函式用法和示例函式
- Sanic response raw() 函式用法和示例函式
- Sanic response file() 函式用法和示例函式
- Sanic response html() 函式用法和示例HTML函式
- Sanic response text() 函式用法和示例函式
- Oracle - DBMS_LOB函式和用法Oracle函式
- $.extend()和$.fn.extend()函式用法函式
- C語言——常用標準輸入輸出函式 scanf(), printf(), gets(), puts(), getchar(), putchar(); 字串拷貝函式 strcpy(), strncpy(), strchr(), strstr()函式用法特點C語言函式字串
- Instr函式的用法函式
- 【Oracle的NVL函式用法】Oracle函式
- fork()函式的基本用法函式
- Oracle dump函式的用法Oracle函式
- openat()函式的用法示例函式
- Oracle trunc()函式的用法Oracle函式
- Oracle 函式 Translate 的用法Oracle函式
- oracle的with函式用法示例Oracle函式
- Translate函式用法函式
- abs函式用法函式
- 使用函式式語言實踐DDD函式