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

大概就是如下一个字符串

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>
#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 

 

 不好意思,刚发首页了,本来是想发预选区的,半夜想起来了,赶紧撤下来。

posted @ 2009-12-12 22:29  蛙蛙王子  Views(2720)  Comments(3Edit  收藏  举报