Learn more about functions such as scanf/getchar/gets/CIN

Source: Internet
Author: User

Scanf (), getchar (), and so on are all standard input functions. Most people think these functions are very simple and there is nothing special about them. However, sometimes it is because the use of these functions does not solve the problem, but cannot find the cause. Let's take a look at a very simple program:

Procedure 1:

# Include <stdio. h>

Int main ()

{

Char success, CH2;

Scanf ("% C", & signature );

Scanf ("% C", & CH2 );

Printf ("% d/N", success, CH2 );

Return 0;

}

Or:

# Include <stdio. h>

Int main ()

{

Char success, CH2;

Response = getchar ();

CH2 = getchar ();

Printf ("% d/N", success, CH2 );

Return 0;

}

The program simply reads two characters from the keyboard and prints the ASCII values of these two characters. However, after executing the program, you will find that the program will not end if a character is entered from the keyboard and the result is printed. For example, if you enter the character 'a', the print result is. Why?

[Analysis ]:

First, let's take a look at the principle of input operations. All input programs have a buffer, that is, the input buffer. The input process is like this. When a keyboard input ends, the input data is stored in the input buffer, and the CIN function directly retrieves data from the input buffer. Because the CIN function retrieves data directly from the buffer zone, sometimes when there is residual data in the buffer zone, the CIN function will directly obtain the residual data without requesting keyboard input, this is why the input statement is invalid in the example!

In fact, 10 is a carriage return! This is because the scanf () and getchar () functions read values from the input stream buffer, rather than from the keyboard (that is, terminal) buffer. When reading, the carriage return (/n) ends, and this/n will be read into the input stream buffer together. Therefore, after receiving the input for the first time, the character/n will be left behind, in this way, the second read function directly removes/n from the buffer. Obviously, the read is successful, so it will not be read from the terminal! This is why this program only ends after one input operation!

----------------------------------------------------

| Problem description 2: (analyze scanf () and gets () to read strings) |

----------------------------------------------------

First, let's take a look at the problem of scanf () Reading strings:

Procedure 2:

# Include <stdio. h>

Int main ()

{

Char str1 [20], str2 [20];

Scanf ("% s", str1 );

Printf ("% s/n", str1 );

Scanf ("% s", str2 );

Printf ("% s/n", str2 );

Return 0;

}

The function of a program is to read a string output and read a string output. We can find that no space exists in the input string, for example:

Test 1 input:

Hello world!

Output:

Hello

World!

[Analysis] The second read operation will not be performed after the program is executed! The cause of this problem is similar to that of the first input Hello world! String Hello world! It will be read into the input buffer, and the scanf () function will stop when it encounters carriage return, space, and tab, that is, the first scanf () will retrieve "hello ", and "world! "It is still in the buffer, so that the second scanf will retrieve the data directly without waiting for input from the terminal.

Test 2:

Hello [enter]

Hello [Output]

World [enter]

World [Output]

[Analysis] The program reads strings from the keyboard twice, indicating that the carriage return at the end of the first input is discarded! That is, the last carriage return is discarded when scanf () reads the string!

 

Let's take a look at how gets () reads strings:

When scanf is used to read a string, spaces are not allowed in the string. Once spaces exist, the subsequent data will be discarded and left in the buffer zone. In fact, another function can accept spaces, that is, gets (). Let's take a look at the application of this function. Let's change program 2:

Procedure 3:

# Include <stdio. h>

Int main ()

{

Char str1 [20], str2 [20];

Gets (str1 );

Printf ("% s/n", str1 );

Gets (str2 );

Printf ("% s/n", str2 );

Return 0;

}

Test:

Hello world! [Input]

Hello world! [Output]

12345 [input]

12345 [Output]

[Analysis] It is obviously different from the execution of the previous program. This time, the program runs two reads from the keyboard, and the first string gets Hello world! The space character is accepted, but not divided into two strings as in the previous program! Therefore, if you want to read a string with a space character, you should use gets () instead of scanf ()!

 

--------------------------------------------------------

| Problem description 3: (getchar () pause the program and view the program execution result) |

--------------------------------------------------------

I don't know if you have encountered such a problem. Some compiler programs do not stop the result interface after execution, but they do not crash, so that they cannot see the execution result. Therefore, many people add the getchar () statement at the end of the program to stop the program after execution, and wait for the terminal to receive a character before terminating the program. But sometimes it is useless, and the program jumps out. Why?

[Analysis] The reason is the same as in the above example because there is data in the input buffer, so getchar () will read the data, so it jumps out!

------------------

| [Summary] |

------------------

First, pay attention to the question of whether different functions accept space characters and whether to discard the last carriage return!

When reading characters:

Scanf () ends an input with space, enter, and tab, and does not discard the last carriage return (that is, the carriage return will remain in the buffer );

Getchar () ends the input with enter and does not discard the last carriage return;

When reading a string:

Scanf () ends an input with space, enter, and Tab

When gets () ends input with enter (the space does not end) and accepts spaces, the last carriage return is discarded!

Second, to avoid the above problems, you must clear the residual data in the buffer zone. You can use the following methods to solve the problem:

Method 1: the C language provides a function to clear the buffer. You only need to clear the buffer before reading the data!

This function is fflush (stdin ).

Method 2: retrieve the residual data in the buffer.

(To be honest, I didn't understand this statement either! Why is format control like this! Hope you can give me some advice !)

Scanf ("% [^/n]", string );

 

C/C ++ Study Notes 2-cin in-depth analysis (I)-cin input operation Processing

In-depth analysis of CIN <, Cin. Get, Cin. Getline, and other functions

Many beginners think that the CIN function is a very simple function! The CIN function has a lot of knowledge to know (for example, what is the return value of CIN, And what member functions are provided by CIN, such as cin. clear (), Cin. ignore (), Cin. fail (), Cin. good () and so on), if you do not have a good grasp of it, you may encounter problems when using it, but you do not know why! In addition, many people have indeed encountered many problems. Below are some simple examples:

Procedure 1:

# Include <iostream>

Using namespace STD;

Int main ()

{

Int M, N;

Cin> m;

Cin> N;

Return 0;

}

Test conditions:

If you enter two valid numbers each time, the program will not go wrong!

However, if you give an invalid input when you enter the 'A' character for the first time, for example, you will find that the program does not

The second input statement is executed. It seems a little strange !!

Procedure 2:

# Include <iostream>

Using namespace STD;

Int main ()

{

Char STR [8];

Cin. Getline (STR, 5 );

Cout <STR <Endl;

Cin. Getline (STR, 5 );

Cout <STR <Endl;

Return 0;

}

The function of the program is very simple, that is, input a string and then output it again. Program execution:

Test 1:

ABCD (Press ENTER)

ABCD (output)

Efgh (Press ENTER)

Efgh (output)

When the number of characters entered for the first time is less than 4, the program runs normally!

Test 2:

Abcdefgh (Press ENTER)

ABCD (output)

(Output-line feed)

When the number of characters entered for the first time is greater than 4, the first string accepts the first four characters, the second input operation is not executed, and the second string output is empty. It seems strange !!!

In fact, many times you will encounter such problems. If you are not familiar with the program input principle and the principles of some functions such as Cin, you do not know how to solve them! I will give a brief introduction here. It may not be very accurate or comprehensive, or there may be some misunderstandings. Please forgive me!

Input Operation Principle

Like the scanf function mentioned in the previous section, the input of a program has a buffer, that is, the input buffer. The input process is like this. When a keyboard input ends, the input data is stored in the input buffer, and the CIN function directly retrieves data from the input buffer. Because the CIN function retrieves data directly from the buffer zone, sometimes when there is residual data in the buffer zone, the CIN function will directly obtain the residual data without requesting keyboard input, this is why the input statement is invalid in the example!

Some Input Functions and operators of CIN

CIN is a extern istream object. Provides many available member functions and heavy-duty operators, such as: CIN <, Cin. Get (), Cin. Getline () and so on. Let's take a look at these functions:

I. Cin <

This operator reads data based on the type of the following variable.

Enter the end condition: Enter, space, and tab are displayed. (This is important !)

Processing of Terminator: discards the terminator (enter, space, Tab) that ends the input in the buffer)

Read characters:

Procedure 3:

# Include <iostream>

Using namespace STD;

Int main ()

{

Char C1, C2;

Cin> C1;

Cin> C2;

Cout <C1 <"" <C2 <Endl;

Return 0;

}

Test 1 input:

A [enter]

B [enter]

Output:

A B

Test 2 input:

A B [enter]

Output:

A B

 

Reading strings:

Procedure 4:

# Include <iostream>

Using namespace STD;

Int main ()

{

Char str1 [10], str2 [10];

Cin> str1;

Cin> str2;

Cout <str1 <Endl;

Cout <str2 <Endl;

Return 0;

}

Test 1 input:

ABCD [enter]

Efgh [enter]

Output:

ABCD

Efgh

[Analysis] it is normal to input a carriage return.

Test 2 input:

ABCD efgh

Output:

ABCD

Efgh

[Analysis] When a string is read for the first time, spaces are stopped. ABCD is read into str1, spaces are discarded, and the subsequent strings are given to the second string. This proves that the process of reading data from CIN ends with a space and discards the space character. There is a residual data room in the buffer zone, and the read operation directly retrieves data from the buffer zone.

 

Ii. Cin. Get ()

The function has three formats: No parameter, one parameter, and two parameters.

That is, Cin. Get (), Cin. Get (char ch), Cin. Get (array_name, arsize)

Read characters:

Enter the end condition: Enter

Processing the Terminator: Do not discard the enter in the buffer

Cin. Get () and CIN. Get (char ch) are used to read characters. Their usage is similar,

That is, CH = cin. Get () is equivalent to CIN. Get (Ch.

Procedure 5:

# Include <iostream>

Using namespace STD;

Int main ()

{

Char C1, C2;

Cin. Get (C1 );

Cin. Get (C2 );

Cout <C1 <"" <C2 <Endl; // print two characters

Cout <(INT) C1 <"" <(INT) C2 <Endl; // print the ASCII values of the two characters

Return 0;

}

Test 1 input:

A [enter]

Output:

A

97 10

[Analysis] only one input from the keyboard is executed. Obviously, the first character is 'A', and the second variable is enter (ASCII value: 10 ), this is because this function does not discard the enter character at the end of the last input, so the buffer left at the end of the first input is the enter character at the end of the last input!

Test 2 input:

A B [enter]

Output:

A

97 32

[Analysis] Obviously, the first character is 'A', and the second variable is space (ASCII value: 32 ). The reason is the same as above. The space character is not discarded.

Reading strings:

Cin. Get (array_name, arsize) is used to read strings and can accept space characters. When the input ends with enter, it reads characters according to the length (arsize) and discards the last enter character.

Procedure 6:

# Include <iostream>

Using namespace STD;

Int main ()

{

Char A [20];

Cin. Get (A, 10 );

Cout <A <Endl;

Return 0;

}

Test 1 input:

ABC def [enter]

Output:

ABC def

[Analysis] indicates that space is acceptable when the function inputs a string.

Test 2 input:

1234567890 [enter]

Output:

123456789

[Analysis] If the input is too long, the data is retrieved Based on the required length.

Procedure 7:

# Include <iostream>

Using namespace STD;

Int main ()

{

Char CH, a [20];

Cin. Get (A, 5 );

Cin> CH;

Cout <A <Endl;

Cout <(INT) CH <Endl;

Return 0;

}

Test 1 input:

12345 [enter]

Output:

1234

53

[Analysis] The first input is too long, and the string is "1234" in length, while the '5' is still in the buffer. Therefore, the second input character is not read from the keyboard, the printed ASCII value is 53 (the ASCII value of '5 ).

Test 2 input:

1234 [enter]

A [enter]

Output:

1234

97

[Analysis] The second input is valid, indicating that the function discards the enter after the first input!

 

Iii. Cin. Getline ()

Cin. Getline () is similar to CIN. Get (array_name, arsize) in Read mode. It ends with enter and can accept space characters. When reading characters by length (arsize), the last enter character is discarded.

However, these two functions are different:

Cin. Get (array_name, arsize) when the input string is too long, it will not cause the CIN function error. Subsequent CIN operations will continue, but will retrieve data directly from the buffer zone. However, when the input of CIN. Getline () is too long, the CIN function will be wrong, and subsequent CIN operations will not be executed. (The specific cause will be detailed in the next section "Troubleshooting of CIN)

Program 8:

# Include <iostream>

Using namespace STD;

Int main ()

{

Char CH, a [20];

Cin. Getline (A, 5 );

Cin> CH;

Cout <A <Endl;

Cout <(INT) CH <Endl;

Return 0;

}

Test input:

12345 [enter]

Output:

1234

-52

[Analysis] and CIN. the get (array_name, arsize) routine will find that the CH here does not read 5 in the buffer, but returns-52. Here, the CIN> CH statement is not executed, this is because the CIN has an error!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.