gets和scanf混用问题

1.gets和scanf的区别
gets可以读入字符串空格,遇见回车才停止
scanf遇见空格或回车都停止读入

2.

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

此时输入数据时需要多输入一行,但只读第一行数据,因为scanf("%d\n",&n);这样一条语句,输入一个数字5加回车,5\n全部被读入到了scanf中去了,然后5被赋给了n,但是这样在缓冲区内此时却没有空白符,因此无法结束,然后根据scanf的规定,必须要有一个空白符才能够结束输入,因此还会要求继续输入,而\n后面需要遇到一个非空白符才能继续读入,否则会一直提示输入,因此再输入一个非空白符,一个空白符即可成功完成scanf的停止。

3.gets和scanf混用
此次问题源于我写的PTA的一道题
题目:
给定n本书的名称和定价,本题要求编写程序,查找并输出其中定价最高和最低的书的名称和定价。

输入格式:
输入第一行给出正整数n(<10),随后给出n本书的信息。每本书在一行中给出书名,即长度不超过30的字符串,随后一行中给出正实数价格。题目保证没有同样价格的书。

输出格式:
在一行中按照“价格, 书名”的格式先后输出价格最高和最低的书。价格保留2位小数。

#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;
}

当我删去scanf(“\n”);时,经过调试发现程序不读下一句gets,原因在于

如果在scanf后用gets需要注意一点,gets是遇到’\n’直接返回,而输入scanf后回车会将’\n’留在输入缓存里,而gets正好遇到’\n’就直接返回了,所以你没有机会输入。

当 gets() 在 scanf() 后,结束输入 scanf() 后回车时,gets()就把回车这个键给接收了。这关键就在于二者使用的结束标记不同。输入字符串时,scanf()遇到空格、回车、Tab结束,但在缓冲区中还留着这些结束符,此后如果使用gets()想去获取下一行字符串,它碰到的却是前面遗留下来的回车(或者回车之前还有空格等空白符),那么这次gets()就直接失效了。

猜测是因为程序开始有一个scanf,输入回车后直接跳过gets,解决方法:

方法1,用一句 while(getchar()!=’\n’); 来处理掉缓冲区里的回车换行符,然后再gets()就正常了。
方法2,如果很明确地就知道缓冲区还留着这么个回车换行符,那就直接读入吧: scanf("\n"); 或者getchar()读入一个字符,然后 接着gets()也就不会有问题了。

扫描二维码关注公众号,回复: 16015116 查看本文章

猜你喜欢

转载自blog.csdn.net/Bad_foxS/article/details/104507135
今日推荐