QQ:3020889729 小蔡
代码结构:
#include
#include "info.h" // 介绍相关
#include "data.h" // 数据相关
#include "fent.h" // 文件相关
int main(int argc, char * argv[])
{
FILE* fp[argc]; // start_index~argc-1 -- 文件指针
char order_set[SET_SIZE][ORDER_SIZE] = {"-h", "-v", "-a", "-ha"}; // 指令集--程序当前拥有的指令
char order_now[ORDER_SIZE] = {0}; // 当前匹配的指令
order_list order_task = NULL; // 程序的指令任务 -- 未设计(更新)
int start_index = 0; // 第一个文件所在参数的索引号
int check_flag = 0; // 检查是否为指令的标志
int auto_flag = 0; // 是否自动添加相关信息到指定文件的标志
char info_str[2][128] = {0}; // 作者信息与相关信息的buf
char model[] = Model_info; // 模板数据
if(argc == 1) // 判断是否输入相关指令和参数
{
printf("Please enter anothor element!(more than 1...)\n");
return -1;
}
else
{
do // 指令排查
{
if(check_flag != 0) ; // 待添加指令任务节点,链表操作
start_index++;
if(start_index == argc) break;
check_flag = _match_order(order_now, argv[start_index], order_set, SET_SIZE);
if(check_flag == 3) {printf("The order %s is wrong!\n", argv[start_index]);return -1;} // 存在伪指令退出
if(check_flag == 2) auto_flag = 1;
}while(check_flag);
// 如果auto_flag=1, 则说明应该开启自动化添加----自动化功能待添加
// 如果auto_flag=0, 则将前两个参数作为author 与 function_info 数据
if(!auto_flag)
{
if(argc >= (start_index+1))
{
info_create(argv[start_index], strlen(argv[start_index]),argv[start_index+1], strlen(argv[start_index+1]), info_str); // 创建完整的介绍信息:author + function_info + model
start_index += 2; // 移动文件起始index往后
}
}
else
{
printf("Auto_function has finished!\n");
}
// 打开文件--并返回文件流指针
// 读写文件
for(int i = start_index; i < argc; ++i)
{
if(!open_file(argv[i], &fp[i])) printf("Open the %s false!(please check the path.)\n", argv[i]); // FILE** file 作为文件参数:方可修改指针的值(一级指针只能修改指针指向的内容)
else
{
printf("Open the %s ok!\n", argv[i]);
write_file(fp[i], info_str, model, strlen(model)); // 写入信息
}
}
}
for(int i = start_index; i < argc; ++i) // 关闭所有打开的文件 -- 注意本身未被使用的文件流不要打开
{
if(!close_file(fp[i])) printf("Close the FP[%d] false!\n", i);
}
printf("\nPRPGRAM OVER!");
return 0;
}
代码结构:
#include "data.h"
// functions:合并输入的自定义介绍信息
// input: 作者信息以及长度, 功能介绍信息以及长度, 整和的字节数据
// return: void
void info_create(const char* author, const int author_len, const char* function_infos, const int function_len, char str[INFO_LEN][INFO_SIZE])
{
for(int i = 0; i < author_len; ++i) // 将数据按字符依次写入第一维
{
str[0][i] = author[i];
}
for(int i = 0; i < function_len; ++i) // 将数据按字符依次写入第二维
{
str[1][i] = function_infos[i];
}
}
// functions:获取时间字符串
// input: char *
// return: void
void get_time_str(char * str)
{
time_t local_t = 0;
struct tm *time_st = NULL;
char * weekdays[7] = {"Sunday", "Monday", "Tuesday", "Wednsday", "Thursday", "Friday", "Saturday"}; // 用于遍历星期几
local_t = time(0); // 当前时间的secs
time_st = localtime(&local_t); // 转换为tm结构体
sprintf(str, "%d-%d-%d %02d:%02d:%02d %s", time_st->tm_year + 1900, time_st->tm_mon + 1, time_st->tm_mday, time_st->tm_hour, time_st->tm_min,time_st->tm_sec, weekdays[time_st->tm_wday]); // 获取字符串
}
代码结构:
#ifndef _DATA_CONFIG_
#define _DATA_CONFIG_
#include
#include
#include
#define INFO_LEN 2
#define INFO_SIZE 128
#define SET_SIZE 4
#define ORDER_SIZE 4
#define ok 1
#define false 0
#define Model_info "\n------------------------------------\n------------------------------------\n/*\n* Author: \n* Function: \n* Time: \n*/\n------------------------------------\n------------------------------------"
typedef unsigned char state; // 函数状态
typedef struct order_lists{
char * order; // 指令
int len; // 指令长度
struct order_lists* next; // 下一个指令节点
}* order_list; // 指令集合
void info_create(const char* author, const int author_len, const char* function_infos, const int function_len, char str[2][128]); // 创建完整介绍信息
void get_time_str(char * str); // 获取时间字符串
#endif
代码结构:
#include "info.h"
/**************************************************/
/* 0.指令部分 */
/**************************************************/
// functions:展示程序帮助信息
// input: void
// return: void
void _help_order_info(void)
{
// 这里采用简单c风格字符串
// 可使用结构体进行链表式创建
char INFO(0)[] = "\nThe -h order:\n";
char INFO(1)[] = "The input and output of the program:\n\n\t -order\n\t author function_info file_paths\n\n";
char INFO(2)[] = "Program instructions use a normal format:\n\n\t program -h\n\t program -v\n\t program -a info_path file_paths\n\t program author function_info file_paths\n\n";
char INFO(3)[] = "Method of application:\n\n\t 1. If you are using the default template, enter the author name with the specified file to be added (avoid Spaces and carriage returns)\n(The introduction will wrap itself)\n\t\t program author function_info file_paths\n\t 2. If you want to use a custom template, create a specific text file and use the -a directive to specify the path:\n\t\t program -a info_txt_path file_paths\n\n";
char MODEL(1)[] = "Model:\n1.FIRST:\n\n\"\n/*\n* Author: xxxxxx\n* Functions: xxxxxx\n* Time: xxxxxx\n*/\n\"\n";
printf("%s%s%s%s%s", INFO(0), INFO(1), INFO(2), INFO(3), MODEL(1));
}
// functions:展示程序版本信息
// input: void
// return: void
void _version_order_info(void)
{
char INFO(0)[] = "\nThe -v order:\n";
char INFO(1)[] = "The program version(user) : 1.0.0\n";
char INFO(2)[] = "(more infomation is waiting to add!)\n\n";
printf("%s%s%s", INFO(0), INFO(1), INFO(2));
}
// functions:展示程序自动信息
// input: void
// return: void
void _auto_order_info(void)
{
char INFO(0)[] = "\nThe -a order:\n";
char INFO(1)[] = "The method of auto order:\n\n\t Writes to the specified file by creating a custom template file as an insert.\n\n";
char INFO(2)[] = "Method of application:\n\n\t program -a info_txt_path file_paths\n\t (info_txt_path: Custom Template; file_paths: File To Insert)\n";
char MODEL(1)[] = "Model:\n1.FIRST:\n\n\"\n/*\n* Author: xxxxxx\n* Functions: xxxxxx\n* Time: xxxxxx\n*/\n\"\n";
printf("%s%s%s%s", INFO(0), INFO(1), INFO(2), MODEL(1));
}
// functions:匹配指令
// input: 当前匹配成功的指令, 待匹配指令, 指令集, 指令集长度----注:指向数组的指针->即指针值为一个数组的地址==二维数组:数组的数组,所以二维数组名就是多个一维数组的首地址
// return: state / auto_flag
state _match_order(char * order_now, const char* order, const char (*order_set)[ORDER_SIZE], int set_len)
{
// 输入的待匹配指令与指令集匹配,并将匹配到的指令存入当前指令中,并返回ok
int order_size = strlen(order); // 当前匹配指令长度
memset(order_now, 0, strlen(order_now)); // 置空指令
int flag = 0;
int error_flag = 0;
if(strncmp(order, "-", 1) == 0) error_flag = 1;
for(int i = 0; i < set_len; ++i)
{
if(strncmp(order, order_set[i], order_size) == 0) {strncpy(order_now, order, order_size); } // 匹配成功就退出
if(strncmp(order_now, "-h", order_size) == 0) {_help_order_info(); flag = 1;break; } // 帮助指令info
if(strncmp(order_now, "-v", order_size) == 0) {_version_order_info(); flag = 2;break; } // 版本指令info
if(strncmp(order_now, "-a", order_size) == 0) { flag = 3;break; } // 自动指令启动标志
if(strncmp(order_now, "-ha", order_size) == 0) {_auto_order_info(); flag = 4;break; } // 自动指令info
}
switch(flag)
{
case 0:
if(error_flag == 1) // 存在假指令使,返回3
return 3;
return 0; // 不能存在时, 返回0, 表示已无指令
break; // return后的break可有可无,这里主要是提醒case默认格式是需要加break结尾的
case 1: // 只要匹配到有的指令就执行相同的return ok
case 2:
case 4:
return ok;
break;
case 3:
return ok +1;
break;
default:
break;
}
}
代码结构:
#ifndef _INFO_CONFIG_
#define _INFO_CONFIG_
#include
#include
#include "data.h"
#define INFO(x) info_##x
#define MODEL(x) model_##x
void _help_order_info(void); // 帮助信息
void _version_order_info(void); // 版本信息
void _auto_order_info(void); // 自动化信息
state _match_order(char * order_now, const char* order, const char (*order_set)[ORDER_SIZE], int set_len); // 匹配指令
#endif
代码结构:
#include "fent.h"
/**************************************************/
/* 1.文件读写部分 */
/**************************************************/
// functions:文件打开
// input: 文件路径,返回的文件流指针
// return: ok, 打开成功; false,失败
state open_file(const char* file_path, FILE** file)
{
// 文件打开模式:a+ -- 追加
*file = fopen(file_path, "r"); // 先用读判断文件是否存在
if(*file == NULL) // 判断是否存在该文件
{
printf("The %s has opened false!(if it is not exit!)\n", file_path);
return false;
}
else
{
fclose(*file);
*file = fopen(file_path, "a+"); // 重新打开,确定文件存在后按追加打开
}
return ok;
}
// functions:文件关闭
// input: 文件流指针
// return: ok, 关闭成功
state close_file(FILE* file)
{
fclose(file);
file = NULL;
return ok;
}
// functions:将模板介绍信息写入指定文件 -- 当前功能仅仅允许在末尾添加
// input: 文件流指针, 介绍内容, 模板信息, 模板字节大小
// return: ok, 关闭成功
state write_file(FILE* file, char info_str[INFO_LEN][INFO_SIZE], const char* information, const int info_size)
{
char* str = (char *)malloc((info_size + INFO_LEN*INFO_SIZE + 1)); // 数组分布:info_size: 模板长度; 2*128 自定义介绍内容长度; 介绍末尾一个换行
char* temp = str;
int len_write = info_size; // 写入的长度: info_size + info_str中有效数据
int ret = 0; // 实际写入
while(*information) // 遍历模板,开始添加相关自定义信息-author等
{
*str = *information;
if(*information == 'A') // 遍历到Author,进入信息补充
{
do
{
str++;
information++;
*str = *information;
}while(*information != ':'); // 复制Author:
str++;
information++;
*str = *information; // 空格复制
int author_index = 0;
while(info_str[0][author_index] != '\0') // 复制自定义的author信息
{
str++;
*str = info_str[0][author_index];
author_index++;
len_write++; // 复制一个字符,意味着添加了一个字符的写入内容
}
}
else if(*information == 'F') // 同上
{
do
{
str++;
information++;
*str = *information;
}while(*information != ':');
str++;
information++;
*str = *information; // 空格复制
int func_index = 0;
while(info_str[1][func_index] != '\0')
{
str++;
*str = info_str[1][func_index];
func_index++;
len_write++;
}
}
else if(*information == 'T')
{
char time_str[INFO_SIZE] = {0};
get_time_str(time_str);
do
{
str++;
information++;
*str = *information;
}while(*information != ':');
str++;
information++;
*str = *information; // 空格复制
int time_index = 0;
while(time_str[time_index] != '\0')
{
str++;
*str = time_str[time_index];
time_index++;
len_write++;
}
}
information++;
str++;
}
*str = '\n';
str++;
len_write++;
*str = '\0'; // 添加字符串结束符--‘\0’
ret = fwrite((void *)temp, 1, len_write, file); // 写入指定的长度
if(!ret) // 如果写入0个字符,说明写入失败
printf("Write is false!\n");
}
代码结构:
#ifndef _FENT_CONFIG_
#define _FENT_CONFIG_
#include "info.h"
#include "data.h"
state open_file(const char* file_path, FILE** file); // 文件以a+打开
state close_file(FILE* file); // 文件关闭
state write_file(FILE* file, char info_str[2][128], const char* information, const int info_size); // 写入文件
#endif
windows通过cmd进入编译后程序所在的行,然后在cmd下进入该目录
尝试启动程序,执行-h,-v指令(未定义的异常指令会报异常,并停止之后的指令读取)
尝试写入文件中
1. 可选择完成在文件首进行添加相关信息(可采用目录操作,使创建的新文件写入完毕后,再移动到添加信息的文件所在的目录下,完成写功能——删除原文件,移入同名的新文件)。
2. 可以添加扫描功能,在文件首尾进行扫描,是否已有文件介绍信息,如果有就添加一行重写时间(reset: 2020-x-x xx:xx:xx 星期x),其它保持不变。
3. 完善auto自动往目录中所有文件添加和检查文件中的介绍信息的功能。
4. 将指令程序引导方式启动转换为,程序启动输入参数启动相关功能。
(program -h 转换为 program 回车 再输入 -h等)
5. 实现多文件添加--当前只允许txt文件~