如标题小括号所示,这是一个垃圾代码,但是还是实现了一部分内容,练习使用,仅供参考
头文件H
#ifndef __FILEPARSETOOLS_H__
#define __FILEPARSETOOLS_H__
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "stdint.h"
#include "stdbool.h"
int8_t findSpec(uint8_t c);
int8_t getLine(uint8_t c);
int8_t parseLineContent(uint8_t *str, uint16_t strLen);
#endif
源代码C
#include "fileParseTools.h"
int8_t findSpec(uint8_t c)
{
uint8_t spec[] = {'<', '>'};
uint16_t len = sizeof(spec) / sizeof(spec[0]);
for (int i = 0; i < len; i++)
{
if (c == spec[i])
{
return 0;
}
}
return -1;
}
#define MAXSTRING_LEN 50 // 最小内容长度,和内存扩展步进
#define MEMORY_EXPANSION_MARGIN 5 // 内存扩展余量余量,留下一定空间填充结束字符和扩展临界值
typedef enum
{
ISLAB_UNKNOWN = -1, // 未知
ISLAB_START, // 标签段开始
ISLAB_STOP, // 标签段结束
} isLab_e;
typedef struct
{
uint8_t *context; // 获取一段标签内容
isLab_e isLab; // 参考 isLab_e
int8_t memExtCount; // 猜测到有可能一段标签内容巨大,所以增加可扩展
uint32_t labelIndex; // 长度,用于字节加入保存
} lineParse_t;
static lineParse_t s_lineParse = {0};
int8_t getLine(uint8_t c)
{
if (s_lineParse.context == NULL)
{
memset(&s_lineParse, 0, sizeof(lineParse_t)); // 初始化所有参数
s_lineParse.context = (uint8_t *)malloc(MAXSTRING_LEN);
memset(s_lineParse.context, 0, MAXSTRING_LEN);
s_lineParse.isLab = ISLAB_UNKNOWN;
s_lineParse.labelIndex = 0;
s_lineParse.memExtCount = 1;
}
if (findSpec(c) == 0)
{
if (c == '<')
{
s_lineParse.isLab = ISLAB_START;
}
else if (c == '>')
{
s_lineParse.isLab = ISLAB_STOP;
}
}
else
{
if (s_lineParse.isLab == ISLAB_STOP)
{
uint16_t len = s_lineParse.labelIndex;
s_lineParse.context[s_lineParse.labelIndex] = '\0';
printf("--->[%s] len %d\n", s_lineParse.context, len);
parseLineContent(s_lineParse.context, len);
memset(s_lineParse.context, 0, MAXSTRING_LEN * s_lineParse.memExtCount);
s_lineParse.labelIndex = 0;
s_lineParse.isLab = ISLAB_UNKNOWN;
}
else if (s_lineParse.isLab == ISLAB_START)
{
// 空间不足,扩展空间
if (s_lineParse.labelIndex > MAXSTRING_LEN * s_lineParse.memExtCount - MEMORY_EXPANSION_MARGIN)
{
s_lineParse.memExtCount++;
s_lineParse.context = realloc(s_lineParse.context, MAXSTRING_LEN * s_lineParse.memExtCount);
// printf("--> space is not enough --- realloc %d index %d addr %c\n", MAXSTRING_LEN * memExtCount, labelIndex, context[labelIndex]);
if (s_lineParse.context == NULL)
{
printf("error !!!\n");
return -1;
}
}
// 保存内容
s_lineParse.context[s_lineParse.labelIndex] = c;
s_lineParse.labelIndex++;
}
}
return 0;
}
#define MAXPARAMS_COUNT 50 // 一个标签段最大可容纳参数个数
typedef enum
{
FINDLABELSTEP_UNKNOWN, // 未知,一般在查找标签名
FINDLABELSTEP_LABELNAME, // 查找标签结束
FINDLABELSTEP_PARAM_NAME, // 查找参数名
FINDLABELSTEP_PARAM_VALUE, // 查找参数值
} findLabelStep_e;
typedef struct
{
uint8_t *labelName; // 保存标签名
uint32_t len, exMemCount, paramIndex; // 必要参数
uint8_t *params[MAXPARAMS_COUNT]; // 参数名称解析后存放指针
uint8_t *paramValue[MAXPARAMS_COUNT]; // 参数内容解析后存放指针
} xml_label_t;
static xml_label_t s_xml_label = {0};
// 解析上面获取的单一行内容,分别归类
int8_t parseLineContent(uint8_t *str, uint16_t strLen)
{
// printf("<%s>\n", str);
if (s_xml_label.labelName == NULL)
{
memset(&s_xml_label, 0, sizeof(xml_label_t)); // 初始化所有参数
s_xml_label.labelName = (uint8_t *)malloc(MAXSTRING_LEN);
memset(s_xml_label.labelName, 0, MAXSTRING_LEN);
s_xml_label.exMemCount = 1;
s_xml_label.paramIndex = 0;
s_xml_label.len = 0;
uint16_t paramsCount = sizeof(s_xml_label.params) / sizeof(s_xml_label.params[0]);
for (uint16_t i = 0; i < paramsCount; i++)
{
s_xml_label.params[i] = NULL;
}
paramsCount = sizeof(s_xml_label.paramValue) / sizeof(s_xml_label.paramValue[0]);
for (uint16_t i = 0; i < paramsCount; i++)
{
s_xml_label.paramValue[i] = NULL;
}
}
//
printf("strlen %d\n", strLen);
findLabelStep_e findStep = FINDLABELSTEP_UNKNOWN;
bool running = false, valueStart = false;
for (uint16_t i = 0; i < strLen; i++)
{
if (str[i] == ' ' && valueStart == false)
{
if (findStep == FINDLABELSTEP_UNKNOWN)
{
findStep = FINDLABELSTEP_LABELNAME;
running = false;
}
// else if (findStep == FINDLABELSTEP_PARAM_VALUE)
// {
// findStep = FINDLABELSTEP_PARAM_NAME;
// running = false;
// }
}
else if (str[i] == '=' && valueStart == false)
{
if (findStep == FINDLABELSTEP_PARAM_NAME)
{
running = false;
}
if (findStep == FINDLABELSTEP_PARAM_VALUE)
{
running = false;
}
}
else if (str[i] == '\"')
{
if (findStep == FINDLABELSTEP_PARAM_VALUE)
{
if (valueStart == true)
{
valueStart = false;
}
running = false;
}
}
else
{
// 分配空间参数重置
if (running == false)
{
if (findStep == FINDLABELSTEP_LABELNAME)
{
s_xml_label.labelName[s_xml_label.len] = '\0';
// printf("lb [%s]\n", s_xml_label.labelName);
s_xml_label.len = 0;
s_xml_label.exMemCount = 1;
findStep = FINDLABELSTEP_PARAM_NAME;
}
else if (findStep == FINDLABELSTEP_PARAM_NAME)
{
s_xml_label.params[s_xml_label.paramIndex][s_xml_label.len] = '\0';
// printf("pn [%d] [%s]\n", s_xml_label.paramIndex, s_xml_label.params[s_xml_label.paramIndex]);
s_xml_label.len = 0;
s_xml_label.exMemCount = 1;
//
findStep = FINDLABELSTEP_PARAM_VALUE;
valueStart = true;
}
else if (findStep == FINDLABELSTEP_PARAM_VALUE)
{
s_xml_label.paramValue[s_xml_label.paramIndex][s_xml_label.len] = '\0';
// printf("pv [%d] [%s]\n", s_xml_label.paramIndex, s_xml_label.paramValue[s_xml_label.paramIndex]);
s_xml_label.len = 0;
s_xml_label.exMemCount = 1;
//
findStep = FINDLABELSTEP_PARAM_NAME;
s_xml_label.paramIndex++;
valueStart = false;
}
running = true;
}
// 查找标签名
if (findStep == FINDLABELSTEP_UNKNOWN)
{
// 空间不足,扩展空间
if (s_xml_label.len > MAXSTRING_LEN * s_xml_label.exMemCount - MEMORY_EXPANSION_MARGIN)
{
s_xml_label.exMemCount++;
s_xml_label.labelName = realloc(s_xml_label.labelName, MAXSTRING_LEN * s_xml_label.exMemCount);
// printf("--> space is not enough --- realloc %d index %d addr %c\n", MAXSTRING_LEN * memExtCount, labelIndex, context[labelIndex]);
if (s_xml_label.labelName == NULL)
{
printf("error !!!\n");
break;
}
}
s_xml_label.labelName[s_xml_label.len] = str[i];
s_xml_label.len++;
}
// 查找参数名
else if (findStep == FINDLABELSTEP_PARAM_NAME)
{
if (s_xml_label.params[s_xml_label.paramIndex] == NULL)
{
s_xml_label.params[s_xml_label.paramIndex] = (uint8_t *)malloc(MAXSTRING_LEN);
memset(s_xml_label.params[s_xml_label.paramIndex], 0, MAXSTRING_LEN);
}
if (s_xml_label.len > MAXSTRING_LEN * s_xml_label.exMemCount - MEMORY_EXPANSION_MARGIN)
{
s_xml_label.exMemCount++;
s_xml_label.params[s_xml_label.paramIndex] = realloc(s_xml_label.params[s_xml_label.paramIndex], MAXSTRING_LEN * s_xml_label.exMemCount);
// printf("--> space is not enough --- realloc %d index %d addr %c\n", MAXSTRING_LEN * memExtCount, labelIndex, context[labelIndex]);
if (s_xml_label.params[s_xml_label.paramIndex] == NULL)
{
printf("error !!!\n");
break;
}
}
s_xml_label.params[s_xml_label.paramIndex][s_xml_label.len] = str[i];
s_xml_label.len++;
}
// 查找参数值
else if (findStep == FINDLABELSTEP_PARAM_VALUE)
{
if (s_xml_label.paramValue[s_xml_label.paramIndex] == NULL)
{
s_xml_label.paramValue[s_xml_label.paramIndex] = (uint8_t *)malloc(MAXSTRING_LEN);
memset(s_xml_label.paramValue[s_xml_label.paramIndex], 0, MAXSTRING_LEN);
}
if (s_xml_label.len > MAXSTRING_LEN * s_xml_label.exMemCount - MEMORY_EXPANSION_MARGIN)
{
s_xml_label.exMemCount++;
s_xml_label.paramValue[s_xml_label.paramIndex] = realloc(s_xml_label.paramValue[s_xml_label.paramIndex], MAXSTRING_LEN * s_xml_label.exMemCount);
// printf("--> space is not enough --- realloc %d index %d addr %c\n", MAXSTRING_LEN * memExtCount, labelIndex, context[labelIndex]);
if (s_xml_label.paramValue[s_xml_label.paramIndex] == NULL)
{
printf("error !!!\n");
break;
}
}
s_xml_label.paramValue[s_xml_label.paramIndex][s_xml_label.len] = str[i];
s_xml_label.len++;
}
}
// printf("[%c] ", str[i]);
// printf("valueStart %d running %d findStep %d s_xml_label.len %d s_xml_label.paramIndex %d s_xml_label.exMemCount %d\n",
// valueStart,
// running,
// findStep,
// s_xml_label.len,
// s_xml_label.paramIndex,
// s_xml_label.exMemCount);
}
// 释放资源
if (s_xml_label.labelName != NULL)
{
printf("labelName: %s\n", s_xml_label.labelName);
free(s_xml_label.labelName);
s_xml_label.labelName = NULL;
}
uint16_t paramsCount = sizeof(s_xml_label.params) / sizeof(s_xml_label.params[0]);
for (uint16_t i = 0; i < paramsCount; i++)
{
if (s_xml_label.params[i] != NULL)
{
printf("param[%d] name [%s]\n", i, s_xml_label.params[i]);
free(s_xml_label.params[i]);
s_xml_label.params[i] = NULL;
}
}
paramsCount = sizeof(s_xml_label.paramValue) / sizeof(s_xml_label.paramValue[0]);
for (uint16_t i = 0; i < paramsCount; i++)
{
if (s_xml_label.paramValue[i] != NULL)
{
printf("param[%d] value [%s]\n", i, s_xml_label.paramValue[i]);
free(s_xml_label.paramValue[i]);
s_xml_label.paramValue[i] = NULL;
}
}
memset(&s_xml_label, 0, sizeof(xml_label_t));
return 0;
}
int main(int argc, char *argv[])
{
printf("param count %d\n", argc);
for (int i = 0; i < argc; i++)
{
printf("param[%d] %s\n", i, argv[i]);
}
if (argc < 2)
{
printf("This tool is only used to parse xml files, and is very basic, for reference only\n");
printf("Usage is as follows: *.exe *.xm\n");
return 0;
}
if ((strcmp(argv[1], "help") == 0) || (strcmp(argv[1], "-h") == 0))
{
printf("This tool is only used to parse xml files, and is very basic, for reference only\n");
printf("Usage is as follows: *.exe *.xm\n");
return 0;
}
FILE *file = NULL;
file = fopen(argv[1], "rb");
if (file == NULL)
{
printf("open file fail\n");
return -1;
}
uint8_t c = ' ';
while (!feof(file))
{
c = fgetc(file);
getLine(c);
}
if (s_lineParse.context != NULL)
{
free(s_lineParse.context);
s_lineParse.context = NULL;
}
printf("parse ok!\n");
fclose(file);
return 0;
}
使用编译器生成可执行文件
gcc .\fileParseTools.c -o .\fileParseTools //生成可执行文件
.\fileParseTools.exe .\ble_sendData.xml //使用
下面是演示,xml文件如图
简单打印结果如下
最后寄语,这个当然是有其他问题的,仅实现了最基础的,还有一些其他毛病但是笔者懒得修了,大概思路就这样了