您的位置:首页 > 编程语言 > C语言/C++

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

2009-12-12 22:08 337 查看
大概就是如下一个字符串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 
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  语言 编程 c token input c#