返回列表 发新帖我要提问本帖赏金: 20.00元(功能说明)

[PIC®/AVR®/dsPIC®产品] gets与scanf连着使用的注意事项你知道吗?

[复制链接]
2975|3
 楼主| gaoyang9992006 发表于 2022-6-14 18:52 | 显示全部楼层 |阅读模式
AN, ge
#申请原创#[url=home.php?mod=space&uid=760190]@21小跑堂 [/url] 事情是这样的,蘑菇群有个朋友听说我懂技术,加了我好友,两个月后的今天终于麻烦到我了。他写了一个C语言的大学课程设计,其中想使用gets()读取一个字符串到一个数组,结果,总是不读,跳过了这条语句,他不知道怎么回事就找到我来问了。程序 如下问题在第81行的gets(beizhu);

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #define MAX 1000

  5. struct date{//日期
  6.         int Year;
  7.         int Month;
  8.         int Day;
  9. };

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

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

  21. void caidan()
  22. {   
  23.         system("cls");
  24.         printf("-------------------财务管理系统-------------------\n");
  25.         printf("                       收入                       \n");
  26.         printf("                    1.添加收入                    \n");
  27.         printf("                    2.查询收入                    \n");
  28.         printf("                    3.删除收入                    \n");
  29.         printf("                    4.修改收入                    \n");
  30.         printf("--------------------------------------------------\n");
  31.         printf("                       支出                       \n");
  32.         printf("                    5.添加支出                    \n");
  33.         printf("                    6.查询支出                    \n");
  34.         printf("                    7.删除支出                    \n");
  35.         printf("                    8.修改支出                    \n");
  36.         printf("--------------------------------------------------\n");
  37.         printf("                     文件操作                     \n");
  38.         printf("                    9.导出                        \n");
  39.         printf("                    0.退出系统                    \n");
  40.         printf("--------------------------------------------------\n");
  41. }

  42. void add(int n,struct shuzu * a){//添加
  43.         int f=1;
  44.         system("cls");//清空页面
  45.         if(a->size==MAX){
  46.                 printf("记录条已经满啦!可以删除一些喔!\n");//记录条上限
  47.         }else{
  48.                 while(f){
  49.                         printf("开始添加信息条吧!\n");//输入信息
  50.                         a->tiao[a->size].Szqk=n;
  51.                         printf("请输入金额\n");
  52.                         double jine;//添加金额
  53.                         scanf("%lf",&jine);
  54.                         a->tiao[a->size].Jine=jine;
  55.                         printf("请选择用途:\n");
  56.                         printf("1.服饰\n");
  57.                         printf("2.餐饮\n");
  58.                         printf("3.出行\n");
  59.                         printf("4.娱乐\n");
  60.                         printf("5.其他\n");
  61.                         int yongtu;//添加用途
  62.                         scanf("%d",&yongtu);
  63.                         a->tiao[a->size].Yongtu=yongtu;
  64.                         int year,month,day;//输入日期
  65.                         printf("请输入年份:\n");
  66.                         scanf("%d",&year);
  67.                         printf("请输入月份:\n");
  68.                         scanf("%d",&month);
  69.                         printf("请输入日子:\n");
  70.                         scanf("%d",&day);
  71.                         a->tiao[a->size].Time.Year=year;//给数组传递日期
  72.                         a->tiao[a->size].Time.Month=month;
  73.                         a->tiao[a->size].Time.Day=day;
  74.                         char beizhu[100];
  75.                         printf("请输入备注(无备注可直接按回车):\n");//输入备注
  76.                         gets(beizhu);
  77.                         for(int i=0;i<strlen(beizhu);i++){
  78.                                 a->tiao[a->size].Beizhu[i]=beizhu[i];
  79.                         }
  80.                         system("cls");//清空数据,告诉用户信息条添加成功。
  81.                         printf("1     ");
  82.                         if(n==1) printf("收入      ");
  83.                         else printf("支出      ");
  84.                         printf("%.1f        ",jine);
  85.                         switch(yongtu){
  86.                                 case 1:
  87.                                         printf("服饰      ");
  88.                                         break;
  89.                                 case 2:
  90.                                         printf("餐饮      ");
  91.                                         break;
  92.                                 case 3:
  93.                                         printf("出行      ");
  94.                                         break;
  95.                                 case 4:
  96.                                         printf("娱乐      ");
  97.                                         break;
  98.                                 case 5:
  99.                                         printf("其他      ");
  100.                                         break;
  101.                         }
  102.                         printf("%d/%d/%d     ",year,month,day);
  103.                         puts(beizhu);
  104.                         printf("\n添加成功!\n");
  105.                         printf("是否需要继续添加信息条(1.是  0.否):");
  106.                         scanf("%d",&f);
  107.                 }
  108.                
  109.         }
  110. }

  111. int main(){
  112.         struct shuzu a;//创建数组
  113.         a.size=0;
  114.         int xz=0;//用户输入选择内容
  115.         while(1){
  116.                 caidan();
  117.                 scanf("%d",&xz);
  118.                 switch(xz){
  119.                         case 1://添加收入信息
  120.                                 a.size++;
  121.                                 add(xz,&a); //地址传递
  122.                                 break;
  123.                         case 2://查询收入信息
  124.                                 break;
  125.                         case 3://删除收入信息
  126.                                 break;
  127.                         case 4://修改收入信息
  128.                                 break;
  129.                         case 5://添加支出信息
  130.                                 break;
  131.                         case 6://查询支出信息
  132.                                 break;
  133.                         case 7://删除支出信息
  134.                                 break;
  135.                         case 8://修改支出信息
  136.                                 break;
  137.                         case 9://打印信息
  138.                                 break;
  139.                         case 0://退出系统
  140.                                 printf("期待下次见面\n");
  141.                                 system("pause");
  142.                                 return 0;
  143.                                 break;
  144.                 }
  145.         }
  146.        
  147.         return 0;
  148. }


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


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





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

打赏榜单

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

评论

发现问题并找到问题的根源,同时将问题解决。问题阐述清晰,解决问题完善。  发表于 2022-6-16 18:00
yangxiaor520 发表于 2022-6-15 07:49 来自手机 | 显示全部楼层
哈哈,浅笑一下。
小明的同学 发表于 2022-6-16 18:33 | 显示全部楼层
让我更进一步的了解了scanf的格式化输入的意义。。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

2052

主题

16402

帖子

222

粉丝
快速回复 在线客服 返回列表 返回顶部