趣味编程:从字符串中提取信息(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 

 

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

你可能感兴趣的:(字符串)