当前位置: 首页 > wzjs >正文

wordpress建站软件app推广地推接单网

wordpress建站软件,app推广地推接单网,温州最好的网站建设公司,腾讯的网络营销模式文章目录 问题背景%d和%c读取缓冲区的差别清空缓存区 问题背景 在写C语言的命令行程序时,我们经常会用到用户输入和标准输出,特别的,当用户输入后,我们发现程序运行不是我们要的样子,这个时候,很可能就是输…

文章目录

    • 问题背景
    • %d和%c读取缓冲区的差别
    • 清空缓存区

问题背景

在写C语言的命令行程序时,我们经常会用到用户输入和标准输出,特别的,当用户输入后,我们发现程序运行不是我们要的样子,这个时候,很可能就是输入缓存区的问题。比如下面这个程序:

//alarm.c
#include <stdio.h>
#include "alarm.h"int main()
{int is_quit = 0;while (is_quit == 0){printf("请输入报警编号(输入`q`退出): ");char alarm_id = '\0';scanf("%c", &alarm_id);if (alarm_id == 'q'){is_quit = 1;break;}alarm_id -= '0';switch ((int)alarm_id){case UPPER_LIMIT_ABS_ALARM:upper_limit_abs_alarm_handler(0, 0);break;case LOWER_LIMIT_ABS_ALARM:lower_limit_abs_alarm_handler(0, 0);break;case UPPER_LIMIT_ABS_HOLD_ALARM:upper_limit_abs_hold_alarm_handler(0, 0);break;case LOWER_LIMIT_ABS_HOLD_ALARM:lower_limit_abs_hold_alarm_handler(0, 0);break;default:break;}}return 0;
}

附alarm.h

//alarm.h
/* 报警类型枚举 */
enum alarm_type
{NO_ALARM,                   /* 无报警 */UPPER_LIMIT_ABS_ALARM,      /* 上限绝对值报警 */LOWER_LIMIT_ABS_ALARM,      /* 下限绝对值报警 */UPPER_LIMIT_ABS_HOLD_ALARM, /* 上限绝对值报警带保持功能 */LOWER_LIMIT_ABS_HOLD_ALARM, /* 下限绝对值报警带保持功能 */
};/** 上限绝对值报警** @param limit 上限* @param process_value 被检测的值* @return 1: 超过上限, 0: 未超过*/
int upper_limit_abs_alarm(int limit, int process_value)
{if (process_value > limit){return 1;}return 0;
}/** 下限绝对值报警** @param limit 下限* @param process_value 被检测的值* @return 1: 低于下限, 0: 未低于*/
int lower_limit_abs_alarm(int limit, int process_value)
{if (process_value < limit){return 1;}return 0;
}
/** 上限绝对值报警带保持功能:所谓保持功能,是指接通电源后,测量值* 即使在报警范围内,也不立即使报警打开,待离开报警范围并再次进入* 报警范围后,才会发出报警。** @param limit 上限* @param process_value 被检测的值* @return 1: 超过上限, 0: 未超过*/
int upper_limit_abs_hold_alarm(int limit, int process_value)
{static int alarm_status = 0;if (alarm_status == 0){if (process_value > limit){alarm_status = 1;}}if (alarm_status == 1){if (process_value > limit){return 1;}}return 0;
}
/** 下限绝对值报警带保持功能:所谓保持功能,是指接通电源后,测量值* 即使在报警范围内,也不立即使报警打开,待离开报警范围并再次进入* 报警范围后,才会发出报警。** @param limit 下限* @param process_value 被检测的值* @return 1: 低于下限, 0: 未低于*/
int lower_limit_abs_hold_alarm(int limit, int process_value)
{static int alarm_status = 0;if (alarm_status == 0){if (process_value < limit){alarm_status = 1;}}if (alarm_status == 1){if (process_value < limit){return 1;}}return 0;
}void upper_limit_abs_alarm_handler(int upper_limit, int process_value)
{printf("请输入报警上限:");scanf("%d", &upper_limit);printf("请输入被检测的值:");scanf("%d", &process_value);if (upper_limit_abs_alarm(upper_limit, process_value)){printf("超过上限\n");}
}
void lower_limit_abs_alarm_handler(int lower_limit, int process_value)
{printf("请输入报警下限: ");scanf("%d", &lower_limit);printf("请输入被检测的值: ");scanf("%d", &process_value);if (lower_limit_abs_alarm(lower_limit, process_value)){printf("低于下限\n");}
}
void upper_limit_abs_hold_alarm_handler(int upper_limit, int process_value)
{printf("请输入报警上限: ");scanf("%d", &upper_limit);printf("请输入被检测的值: ");scanf("%d", &process_value);if (upper_limit_abs_hold_alarm(upper_limit, process_value)){printf("超过上限\n");}
}
void lower_limit_abs_hold_alarm_handler(int lower_limit, int process_value)
{printf("请输入报警下限: ");scanf("%d", &lower_limit);printf("请输入被检测的值: ");scanf("%d", &process_value);if (lower_limit_abs_hold_alarm(lower_limit, process_value)){printf("低于下限\n");}
}

这个程序主要时根据用户输入的报警编号和实际值,确认输出报警信息:“超过上限”,“低于下限”等,程序运行起来后,发现用户输入实际值后,循环执行了两次:

请输入报警编号(输入`q`退出): 1
请输入报警上限:30
请输入被检测的值:40
超过上限
请输入报警编号(输入`q`退出): 请输入报警编号(输入`q`退出): 

这个问题就是由于用的scanf接收%c的输入导致。具体就是:我们循环使用scanf()的时候,如果输入缓冲区还有数据的话,那么scanf()就不会询问用户输入,而是直接就将输入缓冲区的内容拿出来用了,这就导致了前面的错误影响到后面的内容

%d和%c读取缓冲区的差别

对于 %d,在缓冲区中,空格、回车、Tab 键都只是分隔符,不会被 scanf 当成数据取用。%d 遇到它们就跳过,取下一个数据。但是如果是 %c,那么空格、回车、Tab 键都会被当成数据输出给 scanf 取用,例如下面这个程序:

# include <stdio.h>
int main(void)
{int a, c;char b;scanf("%d%c%d", &a, &b, &c);printf("a = %d, b = %c, c = %d\n", a, b, c);return 0;
}

输出如下:

1 5 6
a = 1, b =  , c = 5

解决这个%c的问题,方法有两个:

  1. 既然不想将字符’ ’ 赋给变量 b,那么就先定义一个字符变量 ch,然后用 scanf 将字符 ’ ’ 取出来给变量 ch;
# include <stdio.h>
int main(void)
{int a, c;char b;char ch;scanf("%d%c%d", &a, &b, &ch, &c);printf("a = %d, b = %c, c = %d\n", a, b, c);return 0;
}
  1. 直接清空输入缓冲区。

显然方法二是最简洁的,而且也是通用的。

清空缓存区

清空缓存区的方法也有多种。
第一种:使用 getchar 循环清空缓冲区。但是这个位置比较关键,到底写到哪里比较好。如果对于我们开头提到的程序,如果直接写到scanf函数的后面:

#include <stdio.h>
#include "alarm.h"int main()
{int is_quit = 0;while (is_quit == 0){printf("请输入报警编号(输入`q`退出): ");char alarm_id = '\0';scanf("%c", &alarm_id);// 清空缓冲区int c;while ((c = getchar()) != '\n' && c != EOF);if (alarm_id == 'q'){is_quit = 1;break;}alarm_id -= '0';switch ((int)alarm_id){case UPPER_LIMIT_ABS_ALARM:upper_limit_abs_alarm_handler(0, 0);break;case LOWER_LIMIT_ABS_ALARM:lower_limit_abs_alarm_handler(0, 0);break;case UPPER_LIMIT_ABS_HOLD_ALARM:upper_limit_abs_hold_alarm_handler(0, 0);break;case LOWER_LIMIT_ABS_HOLD_ALARM:lower_limit_abs_hold_alarm_handler(0, 0);break;default:break;}}return 0;
}

这个运行结果:

请输入报警编号(输入`q`退出): 1
请输入报警上限:30
请输入被检测的值:40
超过上限
请输入报警编号(输入`q`退出): 2
请输入报警编号(输入`q`退出): 2
请输入报警下限: 

第二次输入报警编号后,又执行了一次循环体。这个就不对了。原因在于,后面的对于输入的处理之前就清空了缓存区,清空早了,应该在下次scanf之前进行清空,也就是要放到数据处理之后,放到最后:

#include <stdio.h>
#include "alarm.h"int main()
{int is_quit = 0;while (is_quit == 0){printf("请输入报警编号(输入`q`退出): ");char alarm_id = '\0';scanf("%c", &alarm_id);if (alarm_id == 'q'){is_quit = 1;break;}alarm_id -= '0';switch ((int)alarm_id){case UPPER_LIMIT_ABS_ALARM:upper_limit_abs_alarm_handler(0, 0);break;case LOWER_LIMIT_ABS_ALARM:lower_limit_abs_alarm_handler(0, 0);break;case UPPER_LIMIT_ABS_HOLD_ALARM:upper_limit_abs_hold_alarm_handler(0, 0);break;case LOWER_LIMIT_ABS_HOLD_ALARM:lower_limit_abs_hold_alarm_handler(0, 0);break;default:break;}// 清空缓冲区int c;while ((c = getchar()) != '\n' && c != EOF);}return 0;
}

这样程序运行就正常了。

第二种清空缓存区的方法是:使用 fflush(stdin),但是在某些编译器(如 Windows 的 GCC)中,可以使用 fflush(stdin) 清空输入缓冲区。但此方法并非标准 C 的一部分,可能在其他平台上无法正常工作。

推荐采用第一种方法。

http://www.dtcms.com/wzjs/319613.html

相关文章:

  • javaweb做社交网站思路网络营销的收获与体会
  • wordpress站点标题是什么最权威的排行榜网站
  • 网站的开发工具百度查关键词显示排名
  • 龙华做网站的公司软文代写公司
  • 中国b2c平台有哪些黑锋网seo
  • 静态网站设计怎么做怎么在百度上做推广
  • 义乌好品质自适应网站建设天津百度百科
  • 做阀门网站效果怎么样网络推广公司排行榜
  • wordpress 内容 大小限制唐山百度seo公司
  • WordPress文章资讯主题seo有些什么关键词
  • 郓城微信网站建设本地推广最好用的平台
  • 建设局网站安全自查情况报告打开百度浏览器
  • 怎么做网站外贸厦门网站seo哪家好
  • 做织梦网站之前要新建数据库吗网站制作公司有哪些
  • 上海个人网站建设可以搜索任何网站的浏览器
  • 网站建设开发流程按钮引流获客app下载
  • 网站建设项目报价单友情链接是什么意思
  • 昆明做网站的个人大数据营销是什么
  • HTML和PHP怎么做网站常用的seo工具推荐
  • 建设网站前市场分析seo排名怎么看
  • 网站的建设要多少钱枣庄网站建设制作
  • 建设网站审批搜索引擎技术
  • 张家港哪家做企业网站泉州seo代理商
  • 公众号和网站先做哪个免费下载优化大师
  • 中国煤炭建设协会网站seo优化是什么职业
  • 网站开发学习哈尔滨seo关键词
  • 不要钱做网站软件上海网站推广广告
  • 微信二维码网站制作seo收费还是免费
  • 公司做网站注意事项百度自动优化
  • 打扑克观看区免费观看站长工具seo综合查询怎么用