scanf
(2012-05-03 15:31:24)
轉換說明 |
意義 |
%c |
把輸入解釋成一個字符 |
%d |
解釋成一個有符號十進制數 |
%e,%f,%g,%a |
浮點數(%a是C99的標準) |
%E,%F,%G,%A |
浮點數(%A是C99的標準) |
%i |
有符號十進制數 |
%o |
有符號八進制數 |
%x,%X |
有符號十六進制整數 |
%p |
一個指針 |
%s |
一個字符串:輸入內容以第一個非空白字符作爲開始,並且包含直到下一個空白字符的全部字符 |
%u |
無符號十進制整數 |
示例1:
char name[5];
scanf("%s",name);
printf("%s\r\n",name);
printf("sizeof(name)=%d, strlen(name)=%d\r\n",sizeof(name),strlen(name));
1、scanf把一個字符串讀到一個字符數組時,不要用&(也可以加)。格式如下:
char name[5];
scanf("%s",name]);
注意,如果使用數組下標輸入單個字符,則必須使用地址符號,如
char name[5];
scanf("%c",&name[1]);
2、scanf使用空格、製表符和換行符來判斷是否結束輸入,而不是以數組長度來判斷,例如我們輸入的abcdefg,會被全部讀入。
3、scanf用%s輸入時,會自動在後面加上'\0',使其成爲一個字符串,即使輸入的字符數超過數組大小。strlen(name)是從第一個字符開始,到'\0'結束,strlen統計字符數(不含'\0')。
附註:用%s讀入字符串時,有兩種方法停止輸入:第一種就是空白符,遇到空白符,就會停止輸入;第二種就是使用字段寬度,例如s,那麼就最多讀入10個字符,當然,如果還未夠10個字符就已經遇到了空白符,那也要結束讀入,10只是一個最大值。
示例2:
char name[5];
char name2[5];
char ps;
scanf("%s",name);
//if(scanf("%c",&ps)) //標記1
if(scanf("%s",name2))
printf("Hee\n");
註釋掉標記1,保留標記2,運行時,輸入aa,按回車鍵,系統會顯示要我們繼續輸入;
註釋掉標記2,保留標記1,運行時,輸入aa,按回車鍵,系統不會要我們輸入,而是會打印出Hee
程序說明:
4、scanf輸入時,會從第一個非空白字符開始讀入(唯一的例外就是%c),直到再次遇到空白字符時結束,前面的空白字符被丟棄,但後面的空白字符不會丟棄(也就是說%s實際上讀入的是一個單詞)。
所以,保留標記2運行時,先是對name進行輸入,這時回車鍵會留在輸入流。執行語句if(scanf("%s",name2))時,會忽略掉這個回車符,要求我們重新輸入。
5、scanf按%c輸入時,所有輸入字符都是平等的,即使是空白字符,也會讀入,且只讀取一個,剩餘的仍然留在輸入流。也正是因爲它什麼字符都能讀入,所以它的用途很多。
6、scanf如果遇到錯誤的輸入,不會將它丟棄,而是將它留在輸入隊列,因此,如果下次再有一個讀入操作時,就會從它們開始。
示例3:
int age1,age2;
scanf("%d",&age1);
printf("age1=%d\n",age1);
scanf("%d",&age2);
printf("age2=%d\n",age2);
輸入-+12-3,輸出
age1=2
age2=12
程序說明:
7、用%d,它會從第一個非空白字符開始讀入,
1)如果是數字,直接讀入即可。
2)如果是符號,則保存該符號,繼續讀取下一個字符:
Ø
Ø
3)如果是其它字符(既不是空白,也不是數字或+、-符號),將不會讀入任何信息,且該字符會被返回到輸入流。在本示例中,如果第一個非空白字符輸入的是A,則兩個scanf語句都不會讀入任何信息,且A仍留在輸入流中。
現在來看本示例:
(1)兩個變量因爲是自動變量,所以不會初始化,但由於已經分配內存,所以當前值就是原先存在該內存中的值。
(2)執行scanf("%d",&age1);時,首先讀入的是-,系統會暫時保存這個符號,接着讀取下一個符號,+,因爲不是數字符號,所以-會被丟掉,+被返回輸入流。
printf("age1=%d\n",age1);此時打印的是一個垃圾值(上面是2)。
(3)執行scanf("%d",&age2);時,首先讀取的是原先留在輸入流中的+,然後讀取下一個字符,是12,所以age2就被賦予了12.
printf("age1=%d\n",age1);打印出age2=12
8、使用其它數字說明符與使用%d的情況相同,主要區別就是scanf也許會把更多的字符看做數字符號。例如,使用%x,要求輸入十六進制數字,那麼a到f和A到F都會被當成數字符號。而浮點說明符則要求scanf識別小數點、指數計數法、新的p計數法。
scanf連續輸入
示例4:
char age1,age2;
scanf("%c, %c",&age1,&age2);
如果逗號(或任何非空格字符)和第一個%c之間沒有間隔,則輸入時,第一個字符與逗號之間也不能有間隔;如果有空格,則輸入時,第一個字符和逗號之間可以有任意多個字符,也可以是0個。
如果逗號和第二個%c之間沒有間隔,則逗號和第二個輸入字符間也不能有間隔。如果有空格,則輸入時,第二個字符和逗號之間可以有任意多個字符,也可以是0個。
示例5:
int age1,age2;
scanf("%d ,%d",&age1,&age2);
如果逗號和第一個%d之間有空格,則輸入的第一個數字和逗號之間可以有任意(含0)個空格;
如果逗號和第一個%d之間沒有空格,則輸入的第一個數字和逗號之間不能有空格;
逗號和第二個%d之間無論是否有空格,輸入時,逗號和第二個數字之間都可以有任意(含0)個空格。這點和%c不同。
示例6
int age1;
char pet1;
scanf("%c ,%d",&pet1,&age1);
根據示例4和示例5可以推出來:
Ø
Ø
示例7
int age1;
char pet1;
scanf("%d , %c ",&age1,&pet1);
根據示例4和示例5可以推出來:
因爲%d在逗號前面,所以,如果它們之間有空格,則輸入時可含任意(含0)個空格;如果沒有空格,則輸入時也不能含空格;
逗號和%c之間,如有空格,則逗號和字符之間可以有任意(含0)個空格,如果沒有空格,則不能含空格;
總結:
1)當格式符是%c時,不管逗號是在前還是在後,都遵循一條規則:如果彼此之間有空格,則輸入時可含任意(含0)個空格,否則不能含空格;
2)如果是其它格式符(不限於%d),則:
Ø
Ø
補註:
scanf("%c%d",&pet1,&age1);
不管%c和%d之間是否有空格,第一個字符(注意,%c什麼字符都能讀入)和第一個數字之間都可以含任意(含0)個空格。
scanf("%d%c",&age1,&pet1);
如果%d和%c之間有空格,則第一個數字輸完之後,中間可以有任意個字符,然後再是數字;
如果沒有空格,則數字輸完之後必須馬上輸入字符,如果有空格的話,第一個空格將被作爲輸入賦給pet1。
(注意,第一個數字之前可以有任意個空白,都不會被讀入。)
其實%c之所以特別,就是因爲%c對待所有字符都平等。所以在%c之前,如果沒有空格,那麼在輸入時,如果輸入空格,空格就會作爲輸入被讀取;如果%c之前有空格,那就是告訴系統,我們只讀取非空白字符(不限於空格),所以,所有非空白字符都被跳過丟棄。
注意,這跟%c前面有沒有其它格式符或其它符號都無關,例如
scanf("%c%d",&pet1,&age1);
如果我們在%c前面留空格scanf("
對於其它格式符,因爲它會自動跳過空白字符,所以,不管前面是否有空格,輸入時,都可有空白字符。
對於這一塊就要記住兩點:
1、%c的非%c的規則;
2、格式說明符裏所有非空格的字符,如果是在格式說明符前面,遵循第一條;如果是在格式說明符後面,則,不管格式說明符是不是%c,規則都一樣:如果有空格,就可以輸入任意多個空白字符,否則,不能含空白字符。
補充:
scanf連續輸入字符時,可能出錯,因爲第一個scanf需要按下回車鍵才能讀入,但是讀入後,這個回車鍵還在輸入流裏,所以,如果下一個scanf還是讀入字符,就會把這個回車鍵讀進去。
但是如果第二個scanf是讀入其它類型,就不用擔心,因爲除了%c外,用其它格式讀取輸入,都會跳過前面所有空白字符,所以第一個scanf留下的回車鍵會被丟棄。