The problem of mixing gets and scanf

1. The difference between gets and scanf.
Gets can read a string of spaces, and stops when it encounters a carriage return. Scanf
stops reading when it encounters a space or a carriage return.

2.

scanf("%d\n",&a);

At this time, you need to enter one more line when entering data, but only the first line of data is read, because in a statement such as scanf("%d\n",&n);, if you enter a number 5 and press Enter, all 5\n will be read. I went to scanf, and then 5 was assigned to n, but there is no blank character in the buffer at this time, so it cannot end, and then according to the regulations of scanf, there must be a blank character to end the input, so it is still It will ask to continue to input, and \n needs to encounter a non-blank character to continue reading, otherwise it will keep prompting for input, so input another non-blank character, and a blank character can successfully complete the stop of scanf.

3. Gets and scanf are mixed.
This problem stems from a PTA question I wrote.
Title:
Given the name and price of n books, this question requires writing a program to find and output the name and price of the book with the highest and lowest price among them.

Input format:
Input the first line to give a positive integer n (<10), and then give the information of n books. Each book is given the title in one line, which is a string of length no more than 30, followed by a positive real price in one line. The title guarantees that there is no book with the same price.

Output format:
Output the book with the highest price and the lowest price in a row according to the format of "price, book title". Prices retain 2 decimal places.

#include <stdio.h>
#include <stdlib.h>
struct Book
{
    
    
    char name[31];
    double price;
}book;

int main()
{
    
    
    int n;
    scanf("%d",&n);

    struct Book book[n];
    int i,max=0,min=0;
    for(i=0;i<n;i++)
    {
    
    
        scanf("\n");                     //关键所在
        gets(book[i].name);
        scanf("%lf",&book[i].price);
        if(book[i].price>book[max].price)
        {
    
    
            max=i;
        }
        if(book[i].price<book[min].price)
        {
    
    
            min=i;
        }
    }
    printf("%.2lf, %s\n",book[max].price,book[max].name);
    printf("%.2lf, %s\n",book[min].price,book[min].name);
    return 0;
}

When I delete scanf ("\n");, after debugging, I found that the program does not read the next sentence of gets, the reason is that

If you use gets after scanf, you need to pay attention to it. Gets returns directly when it encounters '\n', and enters scanf and press Enter will leave '\n' in the input buffer, and gets happens to encounter '\n' directly is returned, so you don't have a chance to type.

When gets() is after scanf(), and press Enter after finishing inputting scanf(), gets() will receive the key of Enter. The key is that the end tags used by the two are different. When inputting a string, scanf() encounters a space, a carriage return, and the end of a tab, but these terminators are still left in the buffer. After that, if you use gets() to get the next line of string, what it encounters is If there is a carriage return left over from the previous (or there are blanks such as spaces before the carriage return), then this time gets() will directly fail.

The guess is that there is a scanf at the beginning of the program, skip gets directly after entering Enter, the solution:

Method 1, use a while(getchar()!='\n'); to deal with the carriage return and line feed characters in the buffer, and then gets() will be normal.
Method 2, if you clearly know that there is still such a carriage return and line feed in the buffer, then read it directly: scanf("\n"); or getchar() to read a character, and then get() There will be no problem.

Guess you like

Origin blog.csdn.net/Bad_foxS/article/details/104507135