限制程序中某类操作的执行次数的算法设计及C代码实现
2016-08-31 20:40
781 查看
需求描述
编写程序实现限制程序中某类操作的执行次数的需求。为了便于说明,要求程序每天创建一个与上一天不同的文件目录。如果欲创建的文件目录已存在,则不用再创建。文件目录的命名格式为:FileDir_YYYYMMDD,如:FileDir_20160830。
程序流程
对于此类需求,最关键的问题是要设定一个标识来限制操作的执行次数。也就是说,当程序执行完一次操作之后,要有机制来限制它执行第二次操作。
因为本需求要求每天执行一次操作,所有我们自然想到了用日期来限制程序的执行次数。我们可以用一个全局时间变量来存放每次创建文件目录的日期,如果当前日期和全局时间变量中的日期相等,就表示当天已经执行过操作了,不用再次执行。
基于上面的分析,我们可以画出如下的程序流程图:
C代码
程序编译及执行
我们把上面编写好的DirCreateControl.c文件上传到Linux机器上,使用“gcc -g -o DirCreateControlDirCreateControl.c”命令编译之后,生成DirCreateControl文件,然后执行“DirCreateControl”命令,可对程序进行测试。
1)当被创建的目录不存在时,程序执行结果如下:
2)当被创建的目录已经存在时,程序执行结果如下:
可以看到,不管被创建的目录是否存在,程序在一天当中都只执行一次创建目录的操作,而当天剩下的大部分时间都是在检查第二天是否来到,如果没有来到,则继续等待;如果已经来到,则再次重复昨天的操作。
总结
在实际的软件开发项目中,我们经常遇到需要限制程序中某类操作的执行次数的情况,本文只是给出了其中的一种解决办法。在实际编写代码的时候,大家要根据程序的特点及需求要求采用合理的实现方法。
编写程序实现限制程序中某类操作的执行次数的需求。为了便于说明,要求程序每天创建一个与上一天不同的文件目录。如果欲创建的文件目录已存在,则不用再创建。文件目录的命名格式为:FileDir_YYYYMMDD,如:FileDir_20160830。
程序流程
对于此类需求,最关键的问题是要设定一个标识来限制操作的执行次数。也就是说,当程序执行完一次操作之后,要有机制来限制它执行第二次操作。
因为本需求要求每天执行一次操作,所有我们自然想到了用日期来限制程序的执行次数。我们可以用一个全局时间变量来存放每次创建文件目录的日期,如果当前日期和全局时间变量中的日期相等,就表示当天已经执行过操作了,不用再次执行。
基于上面的分析,我们可以画出如下的程序流程图:
C代码
/********************************************************************** * 版权所有 (C)2016, Zhou Zhaoxiong * * 文件名称:DirCreateControl.c * 文件标识:无 * 内容摘要:限制创建目录操作的执行次数的C代码实现 * 其它说明:无 * 当前版本:V1.0 * 作 者:ZhouZhaoxiong * 完成日期:20160830 * **********************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dirent.h> #include <unistd.h> #include <time.h> // 重定义数据类型 typedef signed int INT32; typedef unsigned int UINT32; typedef unsigned char UINT8; typedef unsigned short int UINT16; typedef long int LONG; // 全局变量 UINT8 g_szLastExecDate[10] = {0}; // 上一次执行操作的日期, 格式为: 年月日(YYYYMMDD) // 时间结构体 typedef struct { UINT8 second; /* 0-59 */ UINT8 minute; /* 0-59 */ UINT8 hour; /* 0-23 */ UINT8 day; /* 1-31 */ UINT8 month; /* 1-12 */ UINT16 year; /* 1994-2099 */ UINT8 week; /* 1-7 */ UINT8 Count10ms; /* 0-99 */ } ClockStruc; // 函数声明 void GetCurrentTime(ClockStruc *ptTime); INT32 JudgeIfExecOper(ClockStruc *ptTime); void CreateFileDir(UINT8 *pszFileDir); void Sleep(UINT32 iCountMs); /**************************************************************** * 功能描述: 主函数 * 输入参数: 无 * 输出参数: 无 * 返 回 值: 0-执行完成 * 其他说明: 无 * 修改日期 版本号 修改人 修改内容 *------------------------------------------------------------- * 20160830 V1.0 Zhou Zhaoxiong 创建 ****************************************************************/ INT32 main(void) { ClockStruc tTimeNow = {0}; // 当前时间结构体 UINT8 szFileDir[100] = {0}; // 文件路径变量 INT32 iRetVal = 0; // 执行函数之后的返回值 while (1) // 循环执行创建目录的操作 { Sleep(10 *1000); // 程序执行间隔为10s // 首先判断当天是否已执行过操作 iRetVal = JudgeIfExecOper(&tTimeNow); if (iRetVal != 0) // 不用执行创建目录的操作 { continue; } // 构造目录 snprintf(szFileDir, sizeof(szFileDir)-1,"%s/zhouzx/Test/FileDir_%04d%02d%02d/", getenv("HOME"), tTimeNow.year, tTimeNow.month, tTimeNow.day); // 接着创建目录 CreateFileDir(szFileDir); } return 0; } /********************************************************************** * 功能描述:获取当前时间 * 输入参数:ptTime-当前时间结构体 * 输出参数:ptTime-当前时间结构体 * 返 回 值:无 * 其它说明:无 * 修改日期 版本号 修改人 修改内容 *------------------------------------------------------------------- * 20160830 V1.0 Zhou Zhaoxiong 创建 ***********************************************************************/ void GetCurrentTime(ClockStruc *ptTime) { LONG dt = 0; struct tm *tm1 = NULL; struct timeval tp = {0}; // 获取系统时间 gettimeofday(&tp, NULL); dt = tp.tv_sec; tm1 = localtime(&dt); ptTime->Count10ms = tp.tv_usec / 10000; ptTime->year = (UINT16)(tm1->tm_year + 1900); ptTime->month = (UINT8)tm1->tm_mon + 1; ptTime->day = (UINT8)tm1->tm_mday; ptTime->hour = (UINT8)tm1->tm_hour; ptTime->minute = (UINT8)tm1->tm_min; ptTime->second = (UINT8)tm1->tm_sec; ptTime->week = (UINT8)tm1->tm_wday; if (ptTime->week == 0) // 星期天 { ptTime->week = 7; } } /********************************************************************** * 功能描述:判断当天是否已执行过操作 * 输入参数:ptTime-当前时间结构体 * 输出参数:ptTime-当前时间结构体 * 返 回 值:1-已执行 0-未执行 -1-程序异常 * 其它说明:无 * 修改日期 版本号 修改人 修改内容 * ------------------------------------------------------------------- * 20160830 V1.0 Zhou Zhaoxiong 创建 ***********************************************************************/ INT32 JudgeIfExecOper(ClockStruc *ptTime) { UINT8szCurrentDate[10] = {0}; if (ptTime == NULL) { printf("JudgeIfExecOper: ptTime is NULL!\n"); return -1; } GetCurrentTime(ptTime); // 获取当前时间 snprintf(szCurrentDate, sizeof(szCurrentDate)-1,"%04d%02d%02d", ptTime->year, ptTime->month, ptTime->day); // 判断当前日期和上次执行日期是否相等, 如果相等, 则不用再执行操作了 if (strcmp(szCurrentDate, g_szLastExecDate) != 0) // 两者不相等 { printf("JudgeIfExecOper: CurrentDate is not equal to LastExecDate,so go ahead!\n"); memset(g_szLastExecDate, 0x00, sizeof(g_szLastExecDate)); memcpy(g_szLastExecDate, szCurrentDate, strlen(szCurrentDate)); // 将上次执行日期更新为当前日期 return 0; } else { printf("JudgeIfExecOper: CurrentDate is %s, LastExecDate is %s,they are equal, so do not go ahead!\n", szCurrentDate, g_szLastExecDate); return 1; } } /**************************************************************** * 功能描述: 创建目录 * 输入参数: pszFileDir-目录 * 输出参数: 无 * 返 回 值: 无 * 其他说明: 无 * 修改日期 版本号 修改人 修改内容 * ------------------------------------------------------------- * 20160830 V1.0 Zhou Zhaoxiong 创建 ****************************************************************/ void CreateFileDir(UINT8 *pszFileDir) { UINT8 szCmdbuf[100] = {0}; if (pszFileDir ==NULL) { printf("CreateFileDir: pszFileDir is NULL!\n"); return; } // 下面执行目录创建操作 // 第一步判断目录是否存在 // 第二步创建目录 if (0 != access(pszFileDir, F_OK)) // 目录不存在 { // 创建目录 memset(szCmdbuf,0x00, sizeof(szCmdbuf)); snprintf(szCmdbuf, sizeof(szCmdbuf)-1, "mkdir -p %s",pszFileDir); system(szCmdbuf); printf("CreateFileDir: %s has created successfully!\n",pszFileDir); } else // 目录存在 { printf("CreateFileDir:%s has already existed!\n", pszFileDir); } } /********************************************************************** * 功能描述:程序休眠 * 输入参数:iCountMs-休眠时间(单位:ms) * 输出参数:无 * 返 回 值:无 * 其它说明:无 * 修改日期 版本号 修改人 修改内容 * ------------------------------------------------------------------ * 20160830 V1.0 Zhou Zhaoxiong 创建 ********************************************************************/ void Sleep(UINT32 iCountMs) { struct timevalt_timeout = {0}; if (iCountMs <1000) { t_timeout.tv_sec = 0; t_timeout.tv_usec = iCountMs * 1000; } else { t_timeout.tv_sec = iCountMs /1000; t_timeout.tv_usec = (iCountMs % 1000) * 1000; } select(0, NULL,NULL, NULL, &t_timeout); // 调用select函数阻塞程序 }
程序编译及执行
我们把上面编写好的DirCreateControl.c文件上传到Linux机器上,使用“gcc -g -o DirCreateControlDirCreateControl.c”命令编译之后,生成DirCreateControl文件,然后执行“DirCreateControl”命令,可对程序进行测试。
1)当被创建的目录不存在时,程序执行结果如下:
> DirCreateControl JudgeIfExecOper: CurrentDate is not equal to LastExecDate, sogo ahead! CreateFileDir: /home/zhou/zhouzx/Test/FileDir_20160830/ hascreated successfully! JudgeIfExecOper: CurrentDate is 20160830, LastExecDate is20160830, they are equal, so do not go ahead! JudgeIfExecOper: CurrentDate is 20160830, LastExecDate is20160830, they are equal, so do not go ahead! JudgeIfExecOper: CurrentDate is 20160830, LastExecDate is20160830, they are equal, so do not go ahead! JudgeIfExecOper: CurrentDate is 20160830, LastExecDate is20160830, they are equal, so do not go ahead! JudgeIfExecOper: CurrentDate is 20160830, LastExecDate is20160830, they are equal, so do not go ahead!
2)当被创建的目录已经存在时,程序执行结果如下:
> DirCreateControl JudgeIfExecOper: CurrentDate is not equal to LastExecDate, sogo ahead! CreateFileDir: /home/zhou/zhouzx/Test/FileDir_20160830/ hasalready existed! JudgeIfExecOper: CurrentDate is 20160830, LastExecDate is20160830, they are equal, so do not go ahead! JudgeIfExecOper: CurrentDate is 20160830, LastExecDate is20160830, they are equal, so do not go ahead! JudgeIfExecOper: CurrentDate is 20160830, LastExecDate is20160830, they are equal, so do not go ahead! JudgeIfExecOper: CurrentDate is 20160830, LastExecDate is20160830, they are equal, so do not go ahead! JudgeIfExecOper: CurrentDate is 20160830, LastExecDate is20160830, they are equal, so do not go ahead! JudgeIfExecOper: CurrentDate is 20160830, LastExecDate is20160830, they are equal, so do not go ahead! JudgeIfExecOper: CurrentDate is 20160830, LastExecDate is20160830, they are equal, so do not go ahead! JudgeIfExecOper: CurrentDate is 20160830, LastExecDate is20160830, they are equal, so do not go ahead!
可以看到,不管被创建的目录是否存在,程序在一天当中都只执行一次创建目录的操作,而当天剩下的大部分时间都是在检查第二天是否来到,如果没有来到,则继续等待;如果已经来到,则再次重复昨天的操作。
总结
在实际的软件开发项目中,我们经常遇到需要限制程序中某类操作的执行次数的情况,本文只是给出了其中的一种解决办法。在实际编写代码的时候,大家要根据程序的特点及需求要求采用合理的实现方法。
相关文章推荐
- winform程序如何通过操作注册表来实现限制使用次数
- 【字符串处理算法】最长连续字符及其出现次数的算法设计及C代码实现
- Windows平台下程序日志的设计和实现(下:代码)
- Asp下实现限制IP访问的程序代码
- 系统操作日志设计(二)-代码实现
- JAVA 实现多文件同时操作 程序代码
- WIN32限制程序执行时长功能的实现
- 程序中如何使用代码执行Insert操作
- 系统操作日志设计-代码实现
- 关于FIR设计的切比雪夫最佳逼近法的算法流程和代码实现
- 一个通用的单元测试框架的思考和设计08-实现篇-在testcase代码中执行sql语句
- Java实现程序运行次数限制
- 无操作次数限制的 Undo/Redo 实现方案
- 系统操作日志设计-代码实现
- [构思]设计&实现一个执行Excel的Import&Export操作的类
- 系统操作日志设计(二)-代码实现
- Asp下实现限制IP访问的程序代码
- [VB.NET]点net写client程序传递参数给mssql存储过程insert,为什么要反复执行客户端代码才能成功insert,怎么才能使客户端插入记录操作变得稳定呢?
- AIX 程序设计大赛-AIX正方形问题算法及Java程序实现(方案三)
- 折半查找实现算法二(递归办法)PS:编译后有一个warning,但不影响结果,代码设计上应该还有些问题