2011-10-28 100 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; 
} 
相關問題