The scanf () function is the second function that all C language learners encounter when learning C language (the first function is printf (), Brian W. kerninghan & Dennis M. ritchie's "Hello, world" program is basically the first example for all C language learners. Therefore, scanf () functions should be a function that C learners can skillfully use, however, many beginners cannot use this function very well. In actual programming, the scanf () function is incorrectly used, leading to errors that may occur in the program and failing to run properly, resulting in "scanf () function Bug, scanf () function useless theory, and so on.
In this article, I will explain the problems that I encountered in programming practices and on the Forum. However, the level of my skills is limited (cainiao-level). It is inevitable that there are errors. I also hope that I can give some advice. (Email: knocker.k@126.com)
This article introduces the usage of the scanf () function in C language, and focuses on Common Errors and countermeasures during the use of the scanf () function. Of course, some solutions in this article can be better solved by using other functions and methods, but this article only discusses scanf () function itself.
The first part describes in detail the composition of the scanf () function control string. Next, we will introduce common errors and Countermeasures in the use of scanf () function control strings using actual routines.
Ii. scanf () function control string
Function Name: scanf
Function: format the input.
Usage: int scanf (char * Format [, argument,...]);
The scanf () function is a common terminal formatting input function that reads input information from the standard input device (keyboard. You can read any inherent type of data and automatically convert the value into an appropriate internal format.
The call format is scanf ("<formatted string>", <Address Table> );
The scanf () function returns the number of successfully assigned data items. If an error occurs, EOF is returned.
Its Control string consists of three types of characters:
1. Format the specifier;
2. Blank space character;
3. Non-blank characters;
(A) Format the specifier
Format Character Description
% A reads a floating point value (valid only for c99)
% A same as above
% C reads one character
% D read a decimal integer
% I reads decimal, octal, and hexadecimal Integers
% O read an octal integer
% X reads hexadecimal Integers
% X same as above
% C reads one character
% S reads a string
% F reads a floating point number
% F same as above
% E Same as above
% E Same as above
% G same as above
% G same as above
% P reads a pointer
% U reads an unsigned decimal integer
% N number of equivalent characters that have been read to this point
% [] Scan Character Set combination
% Read % symbol
Additional format description
Modifier description
L/L length modifier input "long" Data
H-length modifier input "short" Data
W integer constant specifies the width of input data
* An asterisk is used to read data.
HH, ll, same as H, l, but only valid for c99.
(B) white space characters
The blank character will slightly remove one or more blank characters in the reading operation of the scanf () function. The blank character can be space, tab, newline, and so on until the first non-blank character appears.
(C) Non-blank characters
A non-blank character will cause the scanf () function to remove the same character as this non-blank character during reading.
Note: The scanf () control string knowledge is introduced here (it should be relatively complete). If any omission occurs, add it next time. The following describes the actual examples.
Iii. Use of the control string of the scanf () function
Example 1.
# Include "stdio. H "<br/> int main (void) <br/>{< br/> int A, B, C; </P> <p> scanf ("% d", & A, & B, & C); <br/> printf ("% d, % d, % d/N ", a, B, c); <br/> return 0; <br/>}< br/>
Enter three values as follows:
3 □4 □5 (enter the values of A, B, and C)
3, 4, 5 (values of A, B, and C output by printf)
(1) The & operator in & A, & B, and & C obtains the memory addresses of these three variables respectively.
(2) "% d" is to input three values in the decimal value format. You can use one or more spaces, Tab keys, and enter keys to separate data.
The following are valid input methods:
① 3 □□□4 □□□5
② 3
4 □5
③ (Tab key) 4
5
Example 2.
# Include "stdio. H "<br/> int main (void) <br/>{< br/> int A, B, C; <br/> scanf (" % d, % d, % d ", & A, & B, & C); <br/> printf (" % d, % d, % d/N ", A, B, C ); <br/> return 0; <br/>}< br/>
Enter three values as follows:
3, 4, 5 (enter the values of A, B, and C)
Or
3, □4, □5 (enter the values of A, B, and C)
3, □□□4, □5 (enter the values of A, B, and C)
......
They are all legal, but "," must be followed by a number, for example:
3 □, 4, □5 is invalid and the program fails. (Solutions and causes will be discussed later)
Another example is:
1. the variables in sacnf () must use addresses.
Int A, B;
Scanf ("% d", a, B); // Error
Scanf ("% d", & A, & B );
2. the scanf () format control string can use other non-blank characters, but these characters must be entered during input.
Example:
Scanf ("% d, % d", & A, & B );
Input: 3, 4 (the comma corresponds to the comma in "% d, % d)
Scanf ("A = % d, B = % d", & A, & B );
Input: A = 3, B = 4 ("A =", "B =", comma and "A =" in "% d, % d ", "B =" corresponds to a comma)
3. When "% C" is used for input, spaces and escape characters are both valid characters.
Example:
Scanf ("% C", & C1, & C2, & C3 );
Input: A □b □c
Result: A → C1, □→ C2, B → C3 (other discarded)
When the scanf () function receives input data, it ends a data input in the following circumstances: (instead of ending the scanf function, the scanf function only has data in each data field and ends after pressing enter ).
① In case of space, "enter", and "Skip" keys.
② End with width.
③ Illegal input.
Write it here in the previous article. The routine in the third section "copy" a tutorial from the Internet (for two reasons: 1. You can play less words. 2. □i don't know how to fight. ^_^), And delete the errors. here, I would also like to remind the readers of this article that everything should be done by yourself. Even classic books have some omissions. Therefore, it is the most reliable to use compilers to speak, yes. If yes, please let the compiler tell you.
I have already expressed two points in the previous article. I would like to reiterate here: 1. This article only discusses the use of scanf () function control strings. All routines in this Article do not constitute programming suggestions. 2. Everything must be done by yourself. Different compilers on different platforms may have different results. All routines in this article are debugged in WIN-TC + Windows ME.
Question 2: Does the scanf () function correctly accept strings with spaces? For example, I love you!
# Include <stdio. h> <br/> int main () <br/>{< br/> char STR [80]; </P> <p> scanf ("% s ", str); <br/> printf ("% s", STR); <br/> return 0; <br/>}< br/>
Input: I live you!
Output: I
When the scanf () function receives input data, it ends a data input in the following circumstances: (instead of ending the scanf function, the scanf function only has data in each data field and ends after pressing enter ).
① In case of space, "enter", and "Skip" keys.
② End with width.
③ Illegal input.
Therefore, the above program cannot achieve the expected purpose. scanf () scans the space after "I" and considers the assignment of STR to an end, and ignores the "love you! ". Note that" love you! "It is still in the keyboard buffer zone (I have seen this on the internet, but after debugging, I found that, in fact, the first and last pointers of the buffer string are equal, that is, the buffer zone is cleared, the scanf () function should only scan the stdin stream, and the residual information is in stdin ). Let's change the above program to verify it:
# Include <stdio. h> <br/> int main () <br/> {<br/> char STR [80]; <br/> char str1 [80]; <br/> char str2 [80]; </P> <p> scanf ("% s", STR);/* enter: I love you! */<Br/> printf ("% s", STR); <br/> sleep (5);/* Wait 5 seconds, tell you where the program is running */<br/> scanf ("% s", str1);/* you do not need to enter the two sentences, scan the keyboard disk buffer. */<br/> scanf ("% s", str2);/* you do not need to enter the two statements, is to scan the keyboard disk buffer */<br/> printf ("/n % s", str1); <br/> printf ("/n % s ", str2); <br/> return 0; <br/>}< br/>
Input: I love you!
Output: I
Love
You!
Okay, the reason is clear. Can the scanf () function complete this task? The answer is yes! Do not forget that the scanf () function has a % [] format controller (if you are not familiar with % [], refer to the previous article). Please refer to the following program:
# Include "stdio. H "<br/> int main () <br/>{< br/> char string [50]; </P> <p>/* scanf ("% s", string); cannot receive space characters */<br/> scanf ("% [^/n]", string); <br/> printf ("% s/n", string); <br/> return 0; <br/>}< br/>
Question 3: residual information of the Keyboard Buffer
# Include <stdio. h> <br/> int main () <br/>{< br/> int A; <br/> char C; <br/> DO <br/> {<br/> scanf ("% d", & A); <br/> scanf ("% C", & C ); <br/> printf ("A = % d c = % C/N", a, c ); <br/>/* printf ("c = % d/N", c); */<br/>} while (C! = 'N'); <br/>}< br/>
Scanf ("% C", & C); why cannot this sentence normally receive characters? We use printf ("c = % d/N", c); Use int to represent C and enable printf ("c = % d/N", C ); in this sentence, let's see what the scanf () function assigns to C. The result is c = 10 and the ASCII value is 10? Line feed:/n. by the way, each time we press the "enter" key, we send a "Press ENTER" (/R) and a "line feed" (/N) to the keyboard buffer ), here/R is processed by the scanf () function (think so ^_^), And/N is assigned to C by the scanf () function "incorrectly.
Solution: Add fflush (stdin) after two scanf () functions, and getch (); getchar () when the statement is added, we will not analyze it here. Let's explore it by yourself. But add fflush (stdin); whatever the situation is feasible.
Function Name: fflush
Function: clears a stream.
Usage: int fflush (File * stream );
# Include <stdio. h> <br/> int main () <br/>{< br/> int A; <br/> char C; <br/> DO <br/> {<br/> scanf ("% d", & A); <br/> fflush (stdin ); <br/> scanf ("% C", & C); <br/> fflush (stdin ); <br/> printf ("A = % d c = % C/N", a, c); <br/>} while (C! = 'N'); <br/>}< br/>
Here is an example of using a space character to process the residual information in the buffer zone:
Run the program with an error:
# Include <stdio. h> <br/> int main () <br/>{< br/> int I; <br/> char J; <br/> for (I = 0; I <10; I ++) <br/>{< br/> scanf ("% C", & J ); /* There is no space before % */<br/>}< br/>
After the space control character is used:
# Include <stdio. h> <br/> int main () <br/>{< br/> int I; <br/> char J; <br/> for (I = 0; I <10; I ++) <br/>{< br/> scanf ("% C", & J ); /* Note that there is a space before % */<br/>}< br/>
You can run it to see how different the two programs are.
Question 4 how to deal with the program deadlock or error caused by incorrect input of the scanf () function?
# Include <stdio. h> <br/> int main () <br/>{< br/> int A, B, C; /* calculate a + B */<br/> scanf ("% d, % d", & A, & B); <br/> C = A + B; <br/> printf ("% d + % d = % d", a, B, c); <br/>}< br/>
If the value of A and B is entered correctly in the above program, there is no problem. However, you cannot ensure that the user can enter the correct value every time. Once the wrong type is entered, your program is not a deadlock, but an incorrect result. Haha, maybe everyone has encountered a problem, right?
Solution: When the scanf () function is successfully executed, the return value is the number of successfully read variables. That is to say, your scanf () function has several variables. If all the scanf () functions are read normally, it returns a few. But pay attention to another problem. If illegal data is input, there may be residual information in the keyboard buffer.
Correct routine:
# Include <stdio. h> <br/> int main () <br/>{< br/> int A, B, C; /* calculate a + B */<br/> while (scanf ("% d, % d", & A, & B )! = 2) fflush (stdin); <br/> C = a + B; <br/> printf ("% d + % d = % d", A, B, c); <br/>}</P> <p>