2011-10-28 60 views
0

4;4=3;1=0,2=2,3=1,4=1,5=1;0003013340f59bce000002aaf01620e620198b2240002710;C /解析字符串,什么是我有一个这样的字符串的最简单的方法

它分离成部分“;”并且每个部分都可以有一个或多个键/值对,如5 = 1等等,如您所见。 我想解析它在纯C,我开始与strtok工作,我在我的代码显示在这里:

const wuint8 section_delimiter[] = ";"; 
const wuint8 field_delimiter[] = ","; 
const wuint8 value_delimiter[] = "="; 

printf("%s\n",data->msg); 

token = strtok(data->msg,section_delimiter); 

while(token != NULL) { 
    indicator = atoi(token); 
    printf("indicator: %d\n", indicator); 
    switch(indicator) { 
     case TYPE_1: { 
      printf("type: %d\n",TYPE_1); 
      wuint16 i, headerType, headerSubType; 

      for(i = 1; i < TP_MAX; i++) { 
       if(i == atoi(token)) { 
        token = strtok(NULL,value_delimiter); 
        headerType = i; 
        headerSubType = atoi(token); 
        break; 
       } 
      } 
      break; 
     } 
     case TYPE_2: { 
      printf("type: %d\n",TYPE_3); 
      break; 
     } 
     case TYPE_3: { 
      printf("type: %d\n",TYPE_3); 
      break; 
     } 
     case TYPE_4: { 
      printf("type: %d\n",TYPE_4); 
      break; 
     } 

我不知道如何正确地做到这一点。 它也变得复杂了,因为不是每个字符串都有相同的结构,有时只有一个或两个部分可以存在。例如:3;4=3;1=0,2=2,3=1,4=1,5=1;

是否有how to这样做是否显示最好和最方便的方式?

+0

请在您的案例中定义“最好”,或删除该条款。 –

+0

为真。改为“最简单”:) – nyyrikki

+0

我会说:分而治之。首先将该行分成三部分,由';'分隔。比:处理单独的部分,也许处于子功能。子功能也可以处理空白部分。 – wildplasser

回答

2

strtok由于其自身管理的全局状态,AFAICR不能用于这样的嵌套循环。 我建议首先解析每个以分号分隔的部分,然后按顺序处理它们 - 或者仅为您的分号实例类似地使用strtok,然后在内部循环中愉快地使用strtok

1

使用strcspn()。固定的缓冲区,结果进入全局变量。数据[]缓冲区被更改(因此需要可写)。 YMMV

/* 
It is separated into sections by ";" and each section can have one or more 
key/value pairs like 5=1 and so on, as you can see. I want to parse it in 
pure C and I started working with strtok as I am showing in code here: 
*/ 
char data[] = "4;4=3;1=0,2=2,3=1,4=1,5=1;0003013340f59bce000002aaf01620e620198b2240002710;" ; 

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

struct header { 
    int l; 
    int r; 
    } headers[123]; 

unsigned nheader; 
int indicator; 
char rest [123]; 

int tokenise(char * buff); 
unsigned tokenise2(struct header *dst, char * buff); 

/****************/ 
int tokenise(char * buff) 
{ 
char *ptrs[14]; 
unsigned nptr; 
unsigned len, pos; 

ptrs[nptr=0] = NULL; 

for (len = pos=0; buff[pos]; pos += len) { 
    len = strcspn(buff+pos, ";"); 
    ptrs[nptr++] = buff+pos; 
    ptrs[nptr] = NULL; 
     if (!buff[pos+len]) break; 
     buff[pos+len] = 0; 
    len +=1; 
    } 

if (nptr> 0 && ptrs[0]) indicator = atoi(ptrs[0]); else indicator = -1; 
if (nptr> 1 && ptrs[1]) nheader = tokenise2 (headers, ptrs[1]); else nheader = 0; 
if (nptr> 2 && ptrs[2]) nheader += tokenise2 (headers+nheader, ptrs[2]); else nheader += 0; 
if (nptr> 3 && ptrs[3]) strcpy (rest, ptrs[3]); else rest[0] = 0; 

return 0; /* or something useful ... */ 
} 
unsigned tokenise2(struct header *target, char * buff) 
{ 
char *ptrs[123]; 
unsigned nptr, iptr; 
unsigned len, pos; 

ptrs[nptr=0] = NULL; 

for (len = pos=0; buff[pos]; pos += len) { 
    len = strcspn(buff+pos, ","); 
    ptrs[nptr++] = buff+pos; 
    ptrs[nptr] = NULL; 
    if (!buff[pos+len]) break; 
    buff[pos+len] = 0; 
    len +=1; 
    } 

for (iptr=0; iptr < nptr; iptr++) { 
    if (! ptrs[iptr]) break; 
    len = strcspn(ptrs[iptr], "="); 
    if (!len) break; 
    target[iptr].l = atoi (ptrs[iptr]); 
    target[iptr].r = atoi (ptrs[iptr]+len+1); 
    } 

return iptr; /* something useful ... */ 
} 

int main(void) 
{ 
int rc; 
unsigned idx; 

fprintf(stderr, "Org=[%s]\n", data); 
rc = tokenise(data); 

printf("Indicator=%d\n", indicator); 
for (idx=0; idx < nheader; idx++) { 
    printf("%u: %d=%d\n", idx, headers[idx].l , headers[idx].r); 
    } 

printf("Rest=%s\n", rest); 

return 0; 
} 
相关问题