没有任何具体价值,单纯的字符串解析、转换的编程练习
/** @file test.c
* @note
* @brief 字符串解析
* @author
* @date
* @note 没有任何具体价值,单纯的字符串解析、转换的编程练习
* @note 历史记录:
* @warning
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct seg
{
char ip[32];
int port;
char name[128];
unsigned int id;
long int bt;
long int et;
}segm_t;
//结构体中的每个字段都可以认为是练习中的一个元素而已,不必在意具体属性
typedef struct test_struct
{
//段信息
struct
{
segm_t *sem_str;
int count;
} segs;
//总信息
struct
{
long bg;
long ed;
} all;
} my_test_struct;
/**@fn parse_elem(char * instr,char *search_str,int *buf_size)
* @brief 截取instr字符串中第一个search_str子串之前的所有内容,并且instr向前移动
* @param instr [IN] - 原始字符串
* search_str [IN] - 参考字符串
* instr [OUT] - 移位之后的字符串
* search_str [IN] - 截取返回的字符串长度
* @return 返回截取的字符串
**/
char *parse_elem(char * instr,char *search_str,int *buf_size)
{
char *str = NULL;
int len = 0;
char buf[256] = {0};
str = strstr(instr,search_str);
if(!str)
{
len = 0;
return NULL;
}
len = str - instr;
memset(buf,0,sizeof(buf));
memcpy(buf,instr,len);
*buf_size = strlen(buf);
//printf("buf:%s\n",buf);
return (char *)buf;
}
/**@fn void print(my_test_struct *test)
* @brief 打印解析好的结构体信息
* @param test [IN] - 原始字符串
* @return
**/
void print(my_test_struct *test)
{
if(!test)
{
return;
}
printf("\n\n\n");
printf("all.bg:%ld\n",test->all.bg);
printf("all.ed:%ld\n",test->all.ed);
printf("test->segs.count:%d\n",test->segs.count);
int i = 0;
my_test_struct *my_t = test;
for(i = 0; i < my_t->segs.count;i++)
{
printf("\n\n##############################\n");
printf("ip:%s\n",my_t->segs.sem_str[i].ip);
printf("port:%d\n",my_t->segs.sem_str[i].port);
printf("name:%s\n",my_t->segs.sem_str[i].name);
printf("id:%d\n",my_t->segs.sem_str[i].id);
printf("bt:%ld\n",my_t->segs.sem_str[i].bt);
printf("et:%ld\n",my_t->segs.sem_str[i].et);
}
}
/**@fn int get_segment_count(char * instr, char *ch )
* @brief 获取循环子串的个数
* @param instr [IN] - 原始字符串
* @param ch [IN] - 分割字符串
* @return 统计的个数
**/
int get_segment_count(char * instr, char *ch )
{
char *str = NULL;
char *buf = instr;
int len = 0;
unsigned int count = 0;
while(buf)
{
str = strstr(buf,ch);
if(str)
{
len = str - buf;
buf = buf + len + strlen(ch);
count++;
}
else
{
buf = NULL;
}
}
return count;
}
/**@fn int parse_url(char *instr,my_test_struct *test)
* @brief 获取循环子串的个数
* @param instr [IN] - 原始字符串
* @param test [OUT] - 转换完成输出的结构体
* @return 状态码
**/
int parse_url(char *instr,my_test_struct *test)
{
char *str = NULL;
int len = 0;
if((!instr) || (!test))
{
return -1;
}
my_test_struct *my_t = test;
my_t->segs.count = get_segment_count(instr,"$");
printf("my_t->segs.count:%d\n",my_t->segs.count);
printf("<%d>instr:%s\n",__LINE__,instr);
//跳过"all:"
str = strstr(instr,":");
len = str - instr;
instr = instr + len + strlen(":");
//bg
str = parse_elem(instr,"#",&len);
my_t->all.bg = atol(str);
instr = instr + len + strlen("#");
//ed
my_t->all.ed = atol(parse_elem(instr,"$",&len));
instr = instr + len + strlen("$");
int i = 0;
my_t->segs.sem_str = (segm_t *)malloc(sizeof(segm_t)*my_t->segs.count);
if(!my_t->segs.sem_str)
{
return -1;
}
//时间段列表
while(instr)
{
memset(my_t->segs.sem_str,0,sizeof(segm_t));
//ip
str = parse_elem(instr,":",&len);
memcpy(my_t->segs.sem_str->ip,str,strlen(str));
instr = instr + len + strlen(":");
//port
my_t->segs.sem_str->port = atol(parse_elem(instr,"/",&len));
instr = instr + len + strlen("/");
//name
str = parse_elem(instr,"#",&len);
memcpy(my_t->segs.sem_str->name,str,strlen(str));
instr = instr + len + strlen("#");
//id
my_t->segs.sem_str->id = atol(parse_elem(instr,"?",&len));
instr = instr + len + strlen("?");
//bt
my_t->segs.sem_str->bt = atol(parse_elem(instr,":",&len));
instr = instr + len + strlen(":");
//et
str = parse_elem(instr,"$",&len);
if(!str)
{
my_t->segs.sem_str->et = atoi(instr);
instr = NULL;
}
else
{
instr = instr + len + strlen("$");
my_t->segs.sem_str->et = atoi(str);
}
my_t->segs.sem_str++;
}
for(i = 0; i < my_t->segs.count;i++)
{
my_t->segs.sem_str--;
}
return 0;
}
int main()
{
//all:<bg>#<ed> <ip>[:port]/<name>#<id>?<bt>:<et> <ip>[:port]/<name>#<id>?<bt>:<et> ...
char *str = "all:111#222$1.1.1.1:3333/aaa#444?555:666$2.2.2.2:7777/bbb#888?999:1010$1.1.1.1:3333/aaa#444?555:666$2.2.2.2:7777/bbb#888?999:1010$1.1.1.1:3333/aaa#444?555:666$2.2.2.2:7777/bbb#888?999:1010$1.1.1.1:3333/aaa#444?555:666$2.2.2.2:7777/bbb#888?999:1010";
int i = 0;
my_test_struct *test = (my_test_struct *)malloc(sizeof(my_test_struct));
if(!test)
{
return -1;
}
memset(test,0,sizeof(my_test_struct));
parse_url(str,test);
print(test);
if(test->segs.sem_str)
{
free(test->segs.sem_str);
test->segs.sem_str = NULL;
}
if(test)
{
free(test);
test = NULL;
}
return 0;
}