C /解析字符串,最简单的方法是什么

时间:2011-10-28 12:01:08

标签: c parsing arrays

我有一个这样的字符串: 4;4=3;1=0,2=2,3=1,4=1,5=1;0003013340f59bce000002aaf01620e620198b2240002710;

它被“;”分成几个部分如您所见,每个部分可以有一个或多个键/值对,如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表示最佳和最便捷的方式?

2 个答案:

答案 0 :(得分:2)

由于它自己管理的全局状态,

strtok不能在这样的嵌套循环中使用AFAICR。 我建议首先解析每个以分号分隔的部分,然后按顺序处理它们 - 或者自己为分号案例实现类似于strtok的东西,然后在内部循环中愉快地使用strtok

答案 1 :(得分:1)

使用strcspn()。固定缓冲区,结果进入全局变量。 data []缓冲区被更改(因此需要可写)。 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;
}