大概就是如下一个字符串
cpu-3.0g--color-red-green-black--price-5000-8000--weight-'3-'--keywords-'levi''s'
要拆分成如下格式
{ "cpu", "3.0g" },
{ "color", "red", "green", "black" },
{ "price", "5000", "8000" },
{ "weight", "3-" },
{ "keywords", "levi's" },
原题目要求地址如下
http://www.cnblogs.com/JeffreyZhao/archive/2009/10/12/code-for-fun-tokenizer.html
老赵的C#语言版本如下
http://www.cnblogs.com/JeffreyZhao/archive/2009/10/21/code-for-fun-tokenizer-answer-1.html
最近学C语言, 我翻译成c语言的了,在dev-c++4.9.9.2编译运行通过,代码如下
#include <stdlib.h>
#define MAX_TOKEN_LEN 20
const e_arg_invalid = -1; /* 错误的参数*/
const e_token_overfllow = -2;/* 数组溢出 */
const s_ok = 0;
int last_error = 0;
void* p1(char ch);
void* p2(char ch);
void* p3(char ch);
void* p4(char ch);
void* p5(char ch);
typedef void* (*fn_parse)(char c);
void aggregate(fn_parse parse, const char* input){
while(*input != '\0'){
if(last_error == s_ok){
parse = ((fn_parse)(&(*parse)))(*input);
input++;
}else{
printf("ocurr an error:%d", last_error);
break;
}
}
}
struct token{
char* inner_token;
int index;
void (*append)(struct token* t, char ch);
};
struct token* current_token;
void append(struct token* t, char ch){
if(t -> index++ > MAX_TOKEN_LEN){
last_error = e_token_overfllow;
return;
}
t -> inner_token[ t -> index ] = ch;
}
void reset(){
current_token = (struct token*)malloc(sizeof(struct token));
current_token -> inner_token = (char*)calloc(MAX_TOKEN_LEN, sizeof(char));
current_token -> index = -1;
}
void dispose(struct token* t)
{
free(t -> inner_token);
free(t);
}
struct token_group{
struct token** tokens;
int index;
};
void append2(struct token_group* g, struct token* t){
struct token* tt;
if( g -> index++ > MAX_TOKEN_LEN ){
last_error = e_token_overfllow;
return;
}
tt = g -> tokens[0];
g -> tokens[g -> index] = t;
}
struct token_group* current_group;
void reset2(){
current_group = (struct token_group*)malloc(sizeof(struct token_group));
current_group -> index = -1;
current_group -> tokens = (struct token**)calloc(MAX_TOKEN_LEN, sizeof(struct token**));
}
void dispose2(struct token_group* group){
free(group -> tokens);
free(group);
}
struct parse_result{
struct token_group** groups;
int index;
};
void append3(struct parse_result* ret,struct token_group* g){
if( ret -> index++ > MAX_TOKEN_LEN ){
last_error = e_token_overfllow;
return;
}
ret -> groups[ret -> index] = g;
}
struct parse_result* result;
void reset3(){
result = (struct parse_result*)malloc(sizeof(struct parse_result));
result -> index = -1;
result -> groups = (struct token_group**)calloc(MAX_TOKEN_LEN, sizeof(struct token_group**));
}
void dispose3(){
free(result -> groups);
free(result);
}
void* p1(char ch){
if (ch == '-'){
last_error = e_arg_invalid;
return NULL;
}
if (ch == '\''){
return p5;
}
else{
append(current_token, ch );
return p4;
}
}
void* p2(char ch){
if (ch == '-'){
append3(result, current_group );
reset2();
return p1;
}
else if (ch == '\''){
return p5;
}
else{
append(current_token, ch);
return p4;
}
}
void* p3(char ch){
if (ch == '\''){
append(current_token, '\'');
return p5;
}
else if (ch == '-'){
append2(current_group, current_token);
reset();
return p2;
}
else{
last_error = e_arg_invalid;
return NULL;
}
}
void* p4(char ch){
if (ch == '\''){
last_error = e_arg_invalid;
return NULL;
}
if (ch == '-'){
append2(current_group, current_token);
reset();
return p2;
}
else{
append(current_token, ch);
return p4;
}
}
void* p5(char ch){
if (ch == '\''){
return p3;
}
else {
append(current_token, ch);
return p5;
}
}
void test_parse(){
int i, j;
struct token_group* group;
struct token* t;
reset();
reset2();
reset3();
char* str = "cpu-3.0g--color-red-green-black--price-5000-8000--weight-'3-'--keywords-'levi''s'";
aggregate(&p1, str);
append2(current_group, current_token);
append3(result, current_group );
for(i = 0; i <= result -> index; i++){
group = result -> groups[i];
printf("group:%d\r\n", i);
for(j = 0; j <= group -> index; j++){
t = group -> tokens[j];
printf("\ttoken:%d-%s\r\n", j, t -> inner_token);
}
}
for(i = 0; i <= result -> index; i++){
group = result -> groups[i];
for(j = 0; j <= group -> index; j++){
t = group -> tokens[j];
dispose(t);
}
dispose2(group);
}
dispose3(result);
}
int main(void)
{
int key;
test_parse();
scanf("%d",&key);
}
运行结果如下:
group:0
token:0-cpu
token:1-3.0g
group:1
token:0-color
token:1-red
token:2-green
token:3-black
group:2
token:0-price
token:1-5000
token:2-8000
group:3
token:0-weight
token:1-3-
group:4
token:0-keywords
token:1-levi's
不好意思,刚发首页了,本来是想发预选区的,半夜想起来了,赶紧撤下来。