趣味编程:从字符串中提取信息(C语言版本)

来源:互联网 发布:mac向上的箭头 编辑:程序博客网 时间:2024/05/17 02:08

大概就是如下一个字符串

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 <stdio.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, 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){
     
if(t -> index++ > MAX_TOKEN_LEN){
         last_error = e_token_overfllow;
         
return;
     }
     t -> inner_token[ t -> index ] = ch;
}
struct token* current_token;
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;
}

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**));
}

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* 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];
         free(t -> inner_token);
         free(t);
      }
      free(group -> tokens);
      free(group);
   }
   free(result -> groups);
}

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 

 

 

原创粉丝点击