scanf 用法大全
int scanf(char *format,...);
這應該是scanf的標準形式。先說說關于他的返回值的問題。
庫函數幾乎都是有返回值的,有些人可能很奇怪,怎么很少人用過scanf的返回值呢?
scanf會返回成功接收到的變量數量的值。比如scanf("%d",&j"),與scanf("%d=",&j),如果接受成功的話返回值都是1
我用如下語句作了測試
#include <stdio.h>
int main (){
????int j;
????printf ("%d",scanf("%d\n",&j));
????return 0;
}
如果你開始就輸入回車,程序會繼續等待你輸入,因為在輸入數字的時候,scanf會跳過空白字符。(the c programming language 上說,scanf實際上是用getchar()接受由數字組成的字符串,再轉換成數字)
如果我輸入ctrl-z(unix上是ctrl-d)則會返回-1(隨編譯器而定).這實際上就是常量EOF的值,也就是所謂的返回eof
如果我鍵入的不是數字返回值就是0。但是如果我輸入浮點數,又會怎么樣呢?
我舉的例子中同樣會返回1,但是緩沖區會留下垃圾,如果是scanf("%d%d",&a,&b);則會出錯。
這是可以使用一個庫函數fflush(stdin)來清除緩沖。不過貌似雨中飛燕大姐說這個用法是非標準的。K&R,只是說行為沒有定義,但我們可以使用while((c=getchar())!='\n'&&c!=EOF);同樣可以清除后面的垃圾
scanf的格式匹配還是比較簡單,一定要記住的就是普通變量一定要加上&,否則編譯器無法檢測錯誤,但運行肯定會段錯誤。
??? ┏━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
??? ┃ 代??碼 │???????????? 意??????????????????????????義???????????? ┃
??? ┠────┼────────────────────────────┨
??? ┃???%a???│讀浮點值(僅適用于 C99)????????????????????????????????? ┃
??? ┃???%A???│讀浮點值(僅適用于 C99)????????????????????????????????? ┃
??? ┃???%c???│讀單字符????????????????????????????????????????????????┃
??? ┃???%d???│讀十進制整數????????????????????????????????????????????┃
??? ┃???%i???│讀十進制、八進制、十六進制整數??????????????????????????┃
??? ┃???%e???│讀浮點數????????????????????????????????????????????????┃
??? ┃???%E???│讀浮點數????????????????????????????????????????????????┃
??? ┃???%f???│讀浮點數????????????????????????????????????????????????┃
??? ┃???%F???│讀浮點數(僅適用于 C99)????????????????????????????????? ┃
??? ┃???%g???│讀浮點數????????????????????????????????????????????????┃
??? ┃???%G???│讀浮點數????????????????????????????????????????????????┃
??? ┃???%o???│讀八進制數????????????????????????????????????????????? ┃
??? ┃???%s???│讀字符串????????????????????????????????????????????????┃
??? ┃???%x???│讀十六進制數????????????????????????????????????????????┃
??? ┃???%X???│讀十六進制數????????????????????????????????????????????┃
??? ┃???%p???│讀指針值????????????????????????????????????????????????┃
??? ┃???%n???│至此已讀入值的等價字符數????????????????????????????????┃
??? ┃???%u???│讀無符號十進制整數??????????????????????????????????????┃
??? ┃??%[ ]??│掃描字符集合????????????????????????????????????????????┃
??? ┃???%%???│讀 % 符號(百分號)???????????????????????????????????????┃
??? ┗━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
前面都很簡單,%p,%n很少用到,跳過。要輸入%必須要在前面再加一個%,
重點來談談%s和%[]。%s是讀入一個數組,他與gets的區別就在于%s會以任何的空字符結束,而gets是回車結束。
同樣%s前可以加數字,表示只讀多少個。
ANSI C 標準向 scanf() 增加了一種新特性,稱為掃描集(scanset)。 掃描集定義一個字符集合,可由 scanf() 讀入其中允許的字符并賦給對應字符數組。 掃描集合由一對方括號中的一串字符定義,左方括號前必須綴以百分號。 例如,以下的掃描集使 scanf() 讀入字符 A、B 和 C:
??? %[ABC]
使用掃描集時,scanf() 連續吃進集合中的字符并放入對應的字符數組,直到發現不在集合中的字符為止(即掃描集僅讀匹配的字符)。返回時,數組中放置以 null 結尾、由讀入字符組成的字符串。
對于許多實現來說,用連字符可以說明一個范圍。 例如,以下掃描集使 scanf() 接受字母 A 到 Z:
%[A-Z]
重要的是要注意掃描集是區分大小寫的。因此,希望掃描大、小寫字符時,應該分別說明大、小寫字母。
對于%[]還可以用^+任意字符(包括eof)來結束字符串的輸入。比如%[^EOF]就是直到有EOF輸入,字符串才中止。
但一定要記住就是c語言是緩沖輸入,即使你%[^a],再你輸入回車之前輸入多少的a都是不可能結束的。
%s的輸入會跳過空白字符,但是%c則不會。
這也就是
scanf("%d",&h);
scanf("%c",&c);
如果這寫的話,變量c放的一定是回車。
如果想實現這種輸入,可以在兩個語句之間加入一個getchar(),他可以吃掉這個回車,
也可用scanf("%d %c",&h,&c);來做,再輸入數字后加一個空格。就可以了
但千萬別用scanf("%d\n",&h)!!!!!!!!k&r說的十分清楚,任何非格式化的字符都需要完全匹配。
意味著,只有輸入數字后面再加\n才是合法的。
還有就是*加在任何項的前面表示該項不符值,別的就沒什么好說的了
Read formatted data from the standard input stream.
int scanf(
???const char* format [,argument]...
);
int wscanf(
???const wchar_t* format [,argument]...
);
Parameters
format
Format control string.
argument
Optional arguments.
Return Values
Both scanf and wscanf return the number of fields converted and assigned; the return value does not include fields that were read but not assigned.
A return value of 0 indicates that no fields were assigned.
The return value is EOF for an error or if the end-of-file character or the end-of-string character is encountered in the first attempt to read a character.
Remarks
The scanf function reads data from the standard input stream stdin and writes the data into the location given by argument.
Each argument must be a pointer to a variable of a type that corresponds to a type specifier in format.
If copying takes place between strings that overlap, the behavior is undefined.
The information here applies to the entire scanf family of functions, including the secure versions and describes the symbols used to tell the scanf functions how to parse the input stream, such as the input stream stdin for scanf, into values that are inserted into program variables.
A format specification has the following form:
% [width] [{h | l | ll | I64 | L}]type
The format argument specifies the interpretation of the input and can contain one or more of the following:
White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.
Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in the input stream does not match, scanf terminates.
Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.
The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in the input stream; the matching characters in the input stream are scanned but not stored. If a character in the input stream conflicts with the format specification, scanf terminates, and the character is left in the input stream as if it had not been read.
When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.
An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.
Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.
The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.
An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.
scanf
<cstdio> int scanf ( const char * format, ... ); Read formatted data from stdin Reads data from stdin and stores them according to the parameter format into the locations pointed by the additional arguments. The additional arguments should point to already allocated objects of the type specified by their corresponding format tag within the format string.Parameters
format- Whitespace character: the function will read and ignore any whitespace characters (this includes blank spaces and the newline and tab characters) which are encountered before the next non-whitespace character. This includes any quantity of whitespace characters, or none.
- Non-whitespace character, except percentage signs (%): Any character that is not either a whitespace character (blank, newline or tab) or part of a format specifier (which begin with a% character) causes the function to read the next character from stdin, compare it to this non-whitespace character and if it matches, it is discarded and the function continues with the next character offormat. If the character does not match, the function fails, returning and leaving subsequent characters ofstdin unread.
- Format specifiers: A sequence formed by an initial percentage sign (%) indicates a format specifier, which is used to specify the type and format of the data to be retrieved fromstdin and stored in the locations pointed by the additional arguments. A format specifier follows this prototype:
%[*][width][modifiers]type
where:
* An optional starting asterisk indicates that the data is to be retrieved fromstdin but ignored, i.e. it is not stored in the corresponding argument. width Specifies the maximum number of characters to be read in the current reading operation modifiers Specifies a size different from int (in the case of d, i and n), unsigned int (in the case of o, u andx) or float (in the case of e, f and g) for the data pointed by the corresponding additional argument:
h : short int (for d, i and n), orunsigned short int (for o, u and x)
l : long int (for d, i and n), orunsigned long int (for o, u and x), or double (fore, f and g)
L : long double (for e, f and g)type A character specifying the type of data to be read and how it is expected to be read. See next table.
scanf type specifiers:typeQualifying InputType of argument c Single character: Reads the next character. If a width different from 1 is specified, the function readswidth characters and stores them in the successive locations of the array passed as argument. No null character is appended at the end. char * d Decimal integer: Number optionally preceded with a + or- sign. int * e,E,f,g,G Floating point: Decimal number containing a decimal point, optionally preceded by a+ or - sign and optionally folowed by the e or E character and a decimal number. Two examples of valid entries are -732.103 and 7.12e4 float * o Octal integer. int * s String of characters. This will read subsequent characters until a whitespace is found (whitespace characters are considered to be blank, newline and tab). char * u Unsigned decimal integer. unsigned int * x,X Hexadecimal integer. int *
For each format specifier in the format string that retrieves data, an additional argument should be specified.
These arguments are expected to be references (pointers): if you want to store the result of afscanf operation on a regular variable you should precede its identifier with thereference operator, i.e. an ampersand sign (&), like in:
int n;
scanf ("%d",&n);
Return Value
On success, the function returns the number of items successfully read. This count can match the expected number of readings or fewer, even zero, if a matching failure happens.In the case of an input failure before any data could be successfully read, EOF is returned.
Example
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* scanf example */ #include <stdio.h>int main () {char str [80];int i;printf ("Enter your family name: ");scanf ("%s",str); printf ("Enter your age: ");scanf ("%d",&i);printf ("Mr. %s , %d years old.\n",str,i);printf ("Enter a hexadecimal number: ");scanf ("%x",&i);printf ("You have entered %#x (%d).\n",i,i);return 0; } |
This example demonstrates some of the types that can be read with scanf:
Enter your family name: Soulie
Enter your age: 29
Mr. Soulie , 29 years old.
Enter a hexadecimal number: ff
You have entered 0xff (255).
scanf函數,與printf函數一樣,都被定義在stdio.h里,因此在使用scanf函數時要加上#include<stdio.h>。它是格式輸入函數,即按用戶指定的格式從鍵盤上把數據輸入到指定的變量之中,其關鍵字最末一個字母f即為“格式”(format)之意。
[編輯本段]scanf函數的一般形式
scanf(格式控制,地址表列)
int scanf(char *format[,argument,...]);
“格式控制”的含義同printf函數;“地址表列”是由若干個地址組成的表列,可以是變量的地址,或字符串首地址。
scanf()函數返回成功賦值的數據項數,出錯時則返回EOF。
例:使用scanf函數輸入數據。
#include<stdio.h>
void main()
{
int a,b,c;
printf("input a,b,c/n");
scanf("%d%d%d",&a,&b,&c);
printf("a=%d,b=%d,c=%d",a,b,c);
}
格式字符說明
%a,%A 讀入一個浮點值(僅C99有效)
%c 讀入一個字符
%d 讀入十進制整數
%i 讀入十進制,八進制,十六進制整數
%o 讀入八進制整數
%x,%X 讀入十六進制整數
%c 讀入一個字符
%s 讀入一個字符串,遇空格、制表符或換行符結束。
%f,%F,%e,%E,%g,%G 用來輸入實數,可以用小數形式或指數形式輸入。
%p 讀入一個指針
%u 讀入一個無符號十進制整數
%n 至此已讀入值的等價字符數
%[] 掃描字符集合
%% 讀%符號
附加格式說明字符表修飾符說明
L/l 長度修飾符 輸入"長"數據
h 長度修飾符 輸入"短"數據
W 整型常數 指定輸入數據所占寬度
* 表示本輸入項在讀入后不賦值給相應的變量
scanf的返回值
scanf的返回值有后面的參數決定
scanf("%d%d", &a, &b);
如果a和b都被成功讀入,那么scanf的返回值就是2
如果只有a被成功讀入,返回值為1
如果a和b都未被成功讀入,返回值為0
如果遇到錯誤或遇到end of file,返回值為EOF。
且返回值為int型.
使用scanf函數時應該注意的問題
1、sacnf()中的變量必須使用地址。
2、scanf()的格式控制串可以使用其它非空白字符,但在輸入時必須輸入這些字符。
3、在用"%c"輸入時,空格和“轉義字符”均作為有效字符。
問題一:scanf()函數不能正確接受有空格的字符串?如: I love you!
#include <stdio.h>
int main()
{
char str[80];
scanf("%s",str);
printf("%s",str);
return 0;
}
輸入:I love you!
輸出:scanf()函數接收輸入數據時,遇以下情況結束一個數據的輸入:(不是結束該scanf函數,scanf函數僅在每一個數據域均有數據,并按回車后結束)。
① 遇空格、“回車”、“跳格”鍵。
② 遇寬度結束。
③ 遇非法輸入。
所以,上述程序并不能達到預期目的,scanf()掃描到"I"后面的空格就認為對str的賦值結束,并忽略后面的"love you!".這里要注意是"love you!"還在鍵盤緩沖區(關于這個問題,網上我所見的說法都是如此,但是,我經過調試發現,其實這時緩沖區字符串首尾指針已經相等了,也就是說緩沖區清空了,scanf()函數應該只是掃描stdin流,這個殘存信息是在stdin中)。我們改動一下上面的程序來驗證一下:
#include <stdio.h>
int main()
{
char str[80];
char str1[80];
char str2[80];
scanf("%s",str);/*此處輸入:I love you! */
printf("%s",str);
sleep(5);/*這里等待5秒,告訴你程序運行到什么地方*/
scanf("%s",str1);/*這兩句無需你再輸入,是對鍵盤盤緩沖區再掃描 */
scanf("%s",str2);/*這兩句無需你再輸入,是對鍵盤盤緩沖區再掃描 */
printf("/n%s",str1);
printf("/n%s",str2);
return 0;
}
輸入:I love you!
輸出:
I
love
you!
好了,原因知道了,那么scanf()函數能不能完成這個任務?回答是:能!別忘了scanf()函數還有一個 %[] 格式控制符(如果對%[]不了解的請查看本文的上篇),請看下面的程序:
#include "stdio.h"
int main()
{
char string[50];/*scanf("%s",string);不能接收空格符*/
scanf("%[^/n]",string);
printf("%s/n",string);
return 0;
}
問題二:鍵盤緩沖區殘余信息問題
#include <stdio.h>
int main()
{
int a;
char c; do
{
scanf("%d",&a);
scanf("%c",&c);
printf("a=%d c=%c/n",a,c);/*printf("c=%d/n",c);*/
}while(c!='N');
}
scanf("%c",&c);這句不能正常接收字符,什么原因呢?我們用printf("c=%d/n",c);將C用int表示出來,啟用printf("c=%d/n",c);這一句,看看scanf()函數賦給C到底是什么,結果是c=10 ,ASCII值為10是什么?換行即/n.對了,我們每擊打一下"Enter"鍵,向鍵盤緩沖區發去一個“回車”(/r),一個“換行"(/n),在這里/r被scanf()函數處理掉了(姑且這么認為吧^_^),而/n被scanf()函數“錯誤”地賦給了c.解決辦法:可以在兩個scanf()函數之后加個fflush(stdin);,還有加getch() , getchar()也可以,但是要視具體scanf()語句加那個,這里就不分析了,讀者自己去摸索吧。但是加fflush(stdin);不管什么情況都可行。
(
函數名: fflush
功 能: 清除一個流
用 法: int fflush(FILE *stream);
)
#include <stdio.h>
int main()
{
int a;
char c; do
{
scanf("%d",&a);
fflush(stdin);
scanf("%c",&c);
fflush(stdin);
printf("a=%d c=%c/n",a,c); }while(c!='N');
}
這里再給一個用“空格符”來處理緩沖區殘余信息的示例:運行出錯的程序:
#include <stdio.h>
int main()
{
int i;
char j;
for(i = 0;i < 10;i++)
{
scanf("%c",&j);/*這里%前沒有空格*/
}
}
使用了空格控制符后:
#include <stdio.h>
int main()
{
int i;
char j;
for(i = 0;i < 10;i++)
{
scanf(" %c",&j);/*注意這里%前有個空格*/
}
}
可以運行看看兩個程序有什么不同。
問題三: 如何處理scanf()函數誤輸入造成程序死鎖或出錯?
#include <stdio.h>
int main()
{
int a,b,c; /*計算a+b*/
scanf("%d,%d",&a,&b);
c=a+b;
printf("%d+%d=%d",a,b,c);
}
如上程序,如果正確輸入a,b的值,那么沒什么問題,但是,你不能保證使用者每一次都能正確輸入,一旦輸入了錯誤的類型,你的程序不是死鎖,就是得到一個錯誤的結果,呵呵,這可能所有人都遇到過的問題吧?解決方法:scanf()函數執行成功時的返回值是成功讀取的變量數,也就是說,你這個scanf()函數有幾個變量,如果scanf()函數全部正常讀取,它就返回幾。但這里還要注意另一個問題,如果輸入了非法數據,鍵盤緩沖區就可能還個有殘余信息問題。正確的例程:
#include <stdio.h>
int main()
{
int a,b,c; /*計算a+b*/
while(scanf("%d,%d",&a,&b)!=2)fflush(stdin);
c=a+b;
printf("%d+%d=%d",a,b,c);
}
補充: fflush(stdin)這個方法在GCC下不可用。(在VC6.0下可以)
以下是 C99 對 fflush 函數的定義:
int fflush(FILE *stream);
如果stream指向輸出流或者更新流(update stream),并且這個更新流
最近執行的操作不是輸入,那么fflush函數將把任何未被寫入的數據寫入stream
指向的文件(如標準輸出文件stdout)。否則,fflush函數的行為是不確定的。
fflush(NULL)清空所有輸出流和上面提到的更新流。如果發生寫錯誤,fflush
函數會給那些流打上錯誤標記,并且返回EOF,否則返回0。
由此可知,如果 stream 指向輸入流(如 stdin),那么 fflush 函數的行為是不確定的。故而使用
fflush(stdin) 是不正確的,至少是移植性不好的。
可采用如下方法:
/* 此函數可以和scanf函數一起使用,但使用%c輸入時要注意,即此函數只能用于緩沖區非空的情況 */
void flush()
{
char c;
while ((c=getchar()) != '/n'&&c!=EOF) ;
}
#include <stdio.h>
int main()
{
int a,b,c; /*計算a+b*/
while(scanf("%d,%d",&a,&b)!=2) flush();
c=a+b;
printf("%d+%d=%d",a,b,c);
}
| down votefavorite 1 share [g+]share [fb] share [tw] | Consider the following code: #include <stdio.h>int main (void) {char str1[128], str2[128], str3[128];printf ("\nEnter str1: ");scanf ("%[^\n]", str1);printf ("\nstr1 = %s", str1);printf ("\nEnter str2: ");scanf ("%[^\n]", str2);printf ("\nstr2 = %s", str2);printf ("\nEnter str3: ");scanf ("%[^\n]", str3);printf ("\nstr2 = %s", str3);printf ("\n");return 0; }When it is executed only the first scanf stops for the prompt. The program does not stop for the nextscanf s. But if the format string is changed from "%[^\n]" to" %[^\n]" (note the blank space before %), then it works okay. Does some existing newline character from the previous input buffer is automatically accepted ? But flushingstdin does not solve this. What is the cause of this. |
總結
以上是生活随笔為你收集整理的scanf 用法大全的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IOS15最标准的纯代码搭建项目
- 下一篇: IOS15之优雅的使用UITableVi