I think , In the input-output function ,scanf() function , It should be the most troublesome , Sometimes it gives us ridiculous results , But there must be a reason ....
First of all, let me make a statement , This log is not an introduction scanf() The use of various formant in the article ( There is no need for that , But you must be able to use it ).
I tried a lot of input , It includes some wrong exercises , Once upon a time scanf() From confusion to soberness , From sober again to confused ...... I don't know when it's the end , Who let C So deep ?
Post it here , I want to see it from time to time , I also want to know if my understanding is wrong , What's wrong ( So I have the cheek , It's on it ).
be careful , Keyboard buffer It is closely related to input , also , Type matching Yes Input is also very important !!
Let's move on to the topic :
scanf The operation of the flow follows the principle of type matching operation , If the type does not match , It will not read the input stream .
As a result, the input stream will be stranded , If the input stream is not empty ,scanf Will not wait for user input , Input directly from the buffer .
however ,scanf() How to match ? stdin What is it ?
There is very little about matching on the Internet , Some details still can't be found .
therefore , I came to a conclusion on my own :
example : scanf("%d,%d",&i,&j); input :12 ,13 enter however ,j!=13. // be careful ,12 There is a space after it ,why?
reason : I explained that , stay scanf() in , Common characters in format string ( Does not include white space characters ) What we do is Strict matching , Because in the format string %d There's one at the back ','
, So enter the middle number 12 After must be a ','.
scanf("1123%s",&str); input :1123aaabb Time str by aaabb, however , input 24aabbdd Time ,
It's going to go wrong , because 1123 Strict matching is required .
in addition : scanf("%d/n",&i); printf("i=%d",i); How to input to output : i=12 ?
It's not what you think it is , Have a chance to try it !
Some examples :
scanf() Is a return value Function of , What is its return value ? How to use this feature ?
scanf() Matching principle in : In this paper The fifth point Specific description ...
scanf() Starting conditions of data format matching in , End condition .
as : %d ,/n End condition of equal type input .
scanf("%d/n",&i);printf("%d",i); input 12 enter , No output ,why?
scanf() End condition of function : When each Formant Match complete , And when there is a return at the end , End of function .
scanf("%s",str) Continuous input 127 You can't continue typing . //TC in ,VC It seems to be 4000 many ..
// Indicates that the keyboard buffer length is one byte ? however stdin->bsize( Buffer size ) In fact 512, And why ?
stdin Data residue in buffer : scanf("%3s",str); c= getchar(); input : aaabbccc enter ,
here str="aaa",c='b'; // Data residue in buffer !
getch() No buffer , Directly receive the characters input on the keyboard .
// In the example above , Add one ch=getch(); however getch() It can't be read bbccc Any one of them , explain
getch() And getchar() It's not the same , And they're right Enter The values read are also different !
An unusual format character : %[] , as scanf("%[a-z]",str);
input : abcdefdsaABCDEF output :str="abcdefdsa" ;
How to use it? scanf() To enter a string with spaces ?
scanf() When handling , One Enter There are two values sent to the buffer : A return (10) , A new line (13). It can be used
getchar() To receive ( however , Can only receive /n, Namely 13).
In a scanf() Add a after the function fflush(stdin) Can clear input data residue ?
scanf("%3s",str); fflush(stdin); c=getchar();
Direct input aaabbbddd enter , c Can you still get value ?
Here is a detailed explanation :
scanf() The return value of the function upon successful execution is the number of variables read successfully ,
in other words , You this scanf() There are several variables , If scanf() All functions read normally , Just go back to it . But here's another problem , If illegal data is entered , There may be residual information in the keyboard buffer .
scanf()- Function is a general terminal format input function , It comes from a standard input device ( keyboard ) Read the input information . Any inherent type of data can be read in and automatically transformed into the appropriate internal format .
sscanf() - Reads data from a string that matches the specified format .
Function prototype :
Int sscanf( string str, string fmt, mixed var1, mixed var2 ... );
int scanf( const char *format [,argument]... );
sscanf And scanf similar , All for input , Just the latter with the screen (stdin) Is the input source , The former takes a fixed string as the input source .
Among them format It can be one or more {%[*] [width] [{h | l | I64 | L}]type | ' ' | '/t' | '/n' |
wrong % Symbol }
as : sscanf("123456", "%s", buf);
puts(buf); // The result is : 123456
The following is mainly about it scanf() Usage of :
scanf The general form of function
scanf( Format control , Address table column )
int scanf(char *format[,argument,...]);
“ Format control ” It has the same meaning as printf function ;“ Address table column ” Is a list of addresses , Can be the address of a variable , Or the first address of the string .
scanf() Function returns the number of data items assigned successfully , Return on error EOF.
notes :
scanf() White space characters ( include /n,space) Will make scanf() Function omits zero or one or more white space characters in input during a read operation , Whitespace can be space,tab, Line break
wait , Until the first non white space character appears .// The next format character is %c It's the same thing . as ,scanf("%d %c",&i,&ch); input :11
A enter ,i=11,ch=A. here ch Not a space .
A non white space character causes scanf() The function removes the same character as this non whitespace character on read in .
as : scanf(" %c",&ch); input : After several carriage returns , input A, ch=A.
scanf("5729%s",str); input : 5729okok str=okok.
But please note : When the first few of the input are not 5729 Time ( Even if you start with a space !), It will go wrong ,str The value does not change .
scanf() in Format character explain
%p Read in a pointer
%[] Scan character set
%n The number of characters equivalent to the value read so far
%s Read in a string , Encounter space , Tab or newline end .
%c %d %i %o %x %X %c
%f Enter a real number , It can be entered in decimal or exponential form .
%F %e %E %g %G
%u Read in an unsigned decimal integer
%% read % Symbol
Additional format description character table modifier explain
L/l Length modifier input " long " data
h Length modifier input " short " data
W Integral constant Specifies the width of the input data
m Specifies the width of the input data
* asterisk Empty reading a data
Combined with the actual routine , One by one :
One : "%d%d%d"
Is to enter three values in decimal format . Input , You can use one or more spaces between two data ,tab key , Enter separated .
"%d,%d,%d"
At run time, enter three values as follows :3,4,5 ↙( input a,b,c Value of ) perhaps 3,□4,□5 ↙( input a,b,c Value of )3,□□□4,□5 ↙( input a,b,c Value of )
................
It's all legal , But input 3□,4□□,5 ↙ error !!!!
// because scanf() The normal characters in the format string are matched exactly !
%c
In use "%c" Input , Spaces and “ Escape character ” As valid characters .
Two : scanf() Function with a non white space character ( Include spaces , Skip , enter ) Start a data input ( %c Except of course ! But pay attention ,gets() Start with any character ! ).
scanf() When the function receives input data , End a data entry if :( It's not the end of the day scanf function ,scanf Function has data only in each data field , And press enter to finish ).
① Encounter space ,“ enter ”,“ Skip ” key .
② End of width .
③ Illegal input .
// It's important here , If there is illegal input , The input of this data is ended , But the illegal data entered is still in the buffer , You can receive it with the corresponding data type ! You can also clear the buffer simply .
// for example :
i=10;
scanf("%s",str);
scanf("%d",&i);
scanf("%s",str2);
printf("%s/n",str);printf("%d/n",i);printf("%s/n",str2);
input : i love!
output : i
10
love!
// because love Yes %d It's a start input (scanf() Start with a non blank ), But because it's illegal ,
So the beginning is the end ,i The value does not change !
Three . scanf() Can the function correctly accept strings with spaces ? as : I love c!
// In fact, it can !!!
char str[80];
scanf("%s",str); // input I love c? // result : output I
analysis : scanf() Scan to "I" The space after that is right str End of assignment for , And ignore the following "love c!" . It should be noted here that "love
c!" It's still in the keyboard buffer
After debugging, we found that , In fact, the first and last pointers of the buffer string are already equal , That means the buffer is empty ,scanf() Function should just scan stdin flow , The remaining information is in the stdin in .
// actually , I tried , use scanf("%s",str) Continuous input 127 After characters , The keyboard buffer doesn't fit , in other words , Do not process the input , Continue typing , There was no response , Only enter enter is valid .
To verify it :
#include
<stdio.h>
int main()
{
char str[80];
char str1[80];
char str2[80];
scanf("%s",str); /* Enter here :I love you! */
printf("%s",str);
sleep(3); /* Wait here 3 second , Tell you where the program runs */
scanf("%s",str1); /* You don't need to type these two sentences , It's rescanning the keyboard buffer */
scanf("%s",str2); /* You don't need to type these two sentences , It's rescanning the keyboard buffer */
printf("/n%s",str1);
printf("/n%s",str2);
return 0;
}
input :I love c!
output :
I
love
c!
that , How to input a string with spaces ?
use gets() Certainly. , But we can also use it scanf(), because ,scanf() There is also an input format character that we don't use very often : "%[]"
special :%*[width] [{h | l | I64 | L}]type Indicates that those meeting the condition are filtered out , The value is not written to the target parameter
Support collection operations : // be similar to regular expression .
%[a-z] Represents a match a reach z Any character in , Greed ( Match as much as possible ) // or : %[a-z1-9] Encounter non a~z,1~9 It's over .
%[aB'] matching a,B,' A member of , Greed // To blame a,b,' The character of is the end .
%[^a] Match not a Any character of , Greed scanf("%[^a]",str);
// input : ffddssaaff Then extract ffddss To string str in . Scan to a It's the end right now .
so , We can use it scanf("%[^/n]",str); To enter a string with spaces . // input :l love c! enter , be str For I love
c!
that scanf("%*[^/]/%[^@]",str); What about the role of ??? // Enter a string , intercept / reach @ Between the string ...
Four : Solve the problem of keyboard buffer pollution . // Namely Residual information , Is this important .
for example :
scanf("%c",&c1);
scanf("%c",&c2);
When input : a enter b enter output c1,c2 Value of : Obviously c2 Not for b.
reason : take c2 use int Show it , have a look scanf() Function assigned to C In the end what is it? , The result is c2=10 .
ASCII The value is 10 What is it? ? Line break /n.
Every time we hit "Enter" key , Send one to the keyboard buffer “ enter ”(/r), One “ Line break "(/n).
ad locum /r cover scanf() Function has been disposed of ( Let's just think so ^_^), and /n cover scanf() function “ error ” The land is given to c.
// It seems that getch() Time , hit ENTER, It's a carriage return , also , It does not pass through the keyboard buffer , That is, the contents of the keyboard buffer have nothing to do with it !!!!!
I did a little experiment :
scanf("%3s",str);
puts(str);
c1=getch();
printf("c1 %d/n",c1);
c2=getchar();
printf("c2 %d/n",c2);
// input aaabcdef output aaa input A output : 65,98 See !!!
// %3s Receive only aaa, Then enter one A, cover getch() receive , After output ,getchar() Continue fetching from the buffer
b , got it .
The best way to solve this kind of problem is : It can be in two scanf() Add a after the function fflush(stdin); // function : Clear a stream usage :
int fflush(FILE *stream);
in addition , There is another method on Baidu Encyclopedia : use getchar() and getch() receive . however , We can see from the experiment above ,
getch() The buffer is not processed , It can't be dealt with scanf() Residual information of .
// You can try it :
scanf("%c",c1);
getch(); // Suppose it is used to receive line breaks .
scanf("%c",c2);
// input A After return : c1 The value is 65,c2 by 13 , Line break .
// actually ,getch() Will wait for an input .
// But getch() Replace with getchar() after , input :A enter B enter , output A B
Five : The following section of the program to enter two numbers , It's the end of the process , It's not the one you expect ,why?
#include<stdio.h>
int main()
{
int a;
printf("input the data/n");
scanf("%d/n",&a); // There's a carriage return here /n, If you use scanf("%d ",&a);
printf("%d",a); // The same thing will happen .
return 0;
}
// input : 11 enter after , No output , Enter the space again , enter ,Tab Any number of , No output , When non blank characters are entered, such as input abc enter , There is output , The output is 11.
// Analyze the reasons ( Not necessarily accurate , It should be explained in this way ):
scanf() Is a terminal formatted input function , That is, by matching Yes Variable !!
rule : for example about " %d/n" :
The first space can be associated with the input buffer's Any number of White space character matching ( Include spaces , enter ,Tab), When the first non white space character is encountered , End its match , Then deal with it %d .
%d It can be matched with consecutive numeric symbols , When the first non numeric symbol is encountered , End match , If the number of matching digits is 0, be %d The corresponding variable value remains unchanged .//
be careful ,%d With any non int Invalid character start matching , Even if it is '.' No exception , If input 12.30 be .30 Will not be read , Instead, it stays in the buffer .
In the same way ,/n And also with One or more Enter,Tab,space matching , Until the first non White space character .
same about "%d": Start matching with the first non white space character in the buffer .
however "%c" It's an exception , It matches the first character in the buffer , Whether blank or not , therefore , handle Characters entered +Enter Time , Be sure to pay attention to them Enter.
So for the example above , Enter as : 11a Time , Press once to output 11, But don't forget , There are also a and /n !!!
Six : of stdin, It's actually a standard input file , by File * type .
therefore , scanf("%s",str); It's equivalent to fscanf(stdin,"%s",str);
however scanf() Can only be used for input 127 The following characters , in other words , Buffer can only hold 127 Characters +'/', So why stdin->bsize For
512 What about ? // stay TC lower .
Technology
Daily Recommendation