scanf()函式的用法和實踐 (轉)

amyz發表於2007-08-16
scanf()函式的用法和實踐 (轉)[@more@]

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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章