发新帖本帖赏金 20.00元(功能说明)我要提问
返回列表
打印
[PIC®/AVR®/dsPIC®产品]

gets与scanf连着使用的注意事项你知道吗?

[复制链接]
2298|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
AN, ge
#申请原创#[url=home.php?mod=space&uid=760190]@21小跑堂 [/url] 事情是这样的,蘑菇群有个朋友听说我懂技术,加了我好友,两个月后的今天终于麻烦到我了。他写了一个C语言的大学课程设计,其中想使用gets()读取一个字符串到一个数组,结果,总是不读,跳过了这条语句,他不知道怎么回事就找到我来问了。程序 如下问题在第81行的gets(beizhu);

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 1000

struct date{//日期
        int Year;
        int Month;
        int Day;
};

struct xinxi{//设计信息结构体
    int Szqk;//收入、支出情况
        double Jine;//金额
        int Yongtu; //用途
        struct date Time;//日期
        char Beizhu[100];//备注
};

struct shuzu{
        struct xinxi tiao[MAX];//信息条
        int size;//当前记录个数
};

void caidan()
{   
        system("cls");
        printf("-------------------财务管理系统-------------------\n");
        printf("                       收入                       \n");
        printf("                    1.添加收入                    \n");
        printf("                    2.查询收入                    \n");
        printf("                    3.删除收入                    \n");
        printf("                    4.修改收入                    \n");
        printf("--------------------------------------------------\n");
        printf("                       支出                       \n");
        printf("                    5.添加支出                    \n");
        printf("                    6.查询支出                    \n");
        printf("                    7.删除支出                    \n");
        printf("                    8.修改支出                    \n");
        printf("--------------------------------------------------\n");
        printf("                     文件操作                     \n");
        printf("                    9.导出                        \n");
        printf("                    0.退出系统                    \n");
        printf("--------------------------------------------------\n");
}

void add(int n,struct shuzu * a){//添加
        int f=1;
        system("cls");//清空页面
        if(a->size==MAX){
                printf("记录条已经满啦!可以删除一些喔!\n");//记录条上限
        }else{
                while(f){
                        printf("开始添加信息条吧!\n");//输入信息
                        a->tiao[a->size].Szqk=n;
                        printf("请输入金额\n");
                        double jine;//添加金额
                        scanf("%lf",&jine);
                        a->tiao[a->size].Jine=jine;
                        printf("请选择用途:\n");
                        printf("1.服饰\n");
                        printf("2.餐饮\n");
                        printf("3.出行\n");
                        printf("4.娱乐\n");
                        printf("5.其他\n");
                        int yongtu;//添加用途
                        scanf("%d",&yongtu);
                        a->tiao[a->size].Yongtu=yongtu;
                        int year,month,day;//输入日期
                        printf("请输入年份:\n");
                        scanf("%d",&year);
                        printf("请输入月份:\n");
                        scanf("%d",&month);
                        printf("请输入日子:\n");
                        scanf("%d",&day);
                        a->tiao[a->size].Time.Year=year;//给数组传递日期
                        a->tiao[a->size].Time.Month=month;
                        a->tiao[a->size].Time.Day=day;
                        char beizhu[100];
                        printf("请输入备注(无备注可直接按回车):\n");//输入备注
                        gets(beizhu);
                        for(int i=0;i<strlen(beizhu);i++){
                                a->tiao[a->size].Beizhu[i]=beizhu[i];
                        }
                        system("cls");//清空数据,告诉用户信息条添加成功。
                        printf("1     ");
                        if(n==1) printf("收入      ");
                        else printf("支出      ");
                        printf("%.1f        ",jine);
                        switch(yongtu){
                                case 1:
                                        printf("服饰      ");
                                        break;
                                case 2:
                                        printf("餐饮      ");
                                        break;
                                case 3:
                                        printf("出行      ");
                                        break;
                                case 4:
                                        printf("娱乐      ");
                                        break;
                                case 5:
                                        printf("其他      ");
                                        break;
                        }
                        printf("%d/%d/%d     ",year,month,day);
                        puts(beizhu);
                        printf("\n添加成功!\n");
                        printf("是否需要继续添加信息条(1.是  0.否):");
                        scanf("%d",&f);
                }
               
        }
}

int main(){
        struct shuzu a;//创建数组
        a.size=0;
        int xz=0;//用户输入选择内容
        while(1){
                caidan();
                scanf("%d",&xz);
                switch(xz){
                        case 1://添加收入信息
                                a.size++;
                                add(xz,&a); //地址传递
                                break;
                        case 2://查询收入信息
                                break;
                        case 3://删除收入信息
                                break;
                        case 4://修改收入信息
                                break;
                        case 5://添加支出信息
                                break;
                        case 6://查询支出信息
                                break;
                        case 7://删除支出信息
                                break;
                        case 8://修改支出信息
                                break;
                        case 9://打印信息
                                break;
                        case 0://退出系统
                                printf("期待下次见面\n");
                                system("pause");
                                return 0;
                                break;
                }
        }
       
        return 0;
}


这是执行的结果,没看到让输入备注信息就到这一步了。
发给我后,我对前后代码进行阅读,发现前面使用的都是scanf进行数据的读取,而这里他突然使用了gets。
根据我的了解,问题就出在这里了。
scanf为格式化输入语句,所谓的格式化,就是严格的按照格式化关键字从数据流读取需要的数据,不需要的多余的控制符,不会去从数据流中取出的。
   scanf("%d",&day); 
                        a->tiao[a->size].Time.Year=year;//给数组传递日期
                        a->tiao[a->size].Time.Month=month;
                        a->tiao[a->size].Time.Day=day;
                        char beizhu[100];
                        printf("请输入备注(无备注可直接按回车):\n");//输入备注
                        gets(beizhu);
注意这一段,前面是个scanf,读取一个整数。那么后面你输入完了数字会干什么呢?会按下回车,这个回车就继续停留在了数据输入流中。
而gets有个特点,就是以读到回车或换行作为结束标志,并丢弃这个回车或换行符。
所以问题出在这里,gets遇到了前面你输入的那个回车,认为结束了,就跳过了。
所以这里就是想法处理掉前面的回车,这里可以用getchar()接管之前的那个回车符号,并什么都不做,以丢弃。
   scanf("%d",&day); 
                        a->tiao[a->size].Time.Year=year;//给数组传递日期
                        a->tiao[a->size].Time.Month=month;
                        a->tiao[a->size].Time.Day=day;
                        char beizhu[100];
                        printf("请输入备注(无备注可直接按回车):\n");//输入备注
                        getchar();
                        gets(beizhu);


所以我们可以在gets()与scanf之间添加一个getchar()解决这个问题。增加了这一句后,程序运行达到了想要的结果了。





使用特权

评论回复

打赏榜单

21小跑堂 打赏了 20.00 元 2022-06-16
理由:恭喜通过原创文章审核!请多多加油哦!

评论
21小跑堂 2022-6-16 18:00 回复TA
发现问题并找到问题的根源,同时将问题解决。问题阐述清晰,解决问题完善。 
沙发
yangxiaor520| | 2022-6-15 07:49 | 只看该作者
哈哈,浅笑一下。

使用特权

评论回复
板凳
小明的同学| | 2022-6-16 18:33 | 只看该作者
让我更进一步的了解了scanf的格式化输入的意义。。

使用特权

评论回复
发新帖 本帖赏金 20.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:西安公路研究院南京院
简介:主要工作从事监控网络与通信网络设计,以及从事基于嵌入式的通信与控制设备研发。擅长单片机嵌入式系统物联网设备开发,音频功放电路开发。

1893

主题

15621

帖子

197

粉丝