嵌套的strtok_r():成功的标记包含父分隔符

时间:2018-06-01 15:11:00

标签: c string parsing

给定的字符串包含键:城市的值对及其距离,我使用strtok_r首先使用";"分隔符分隔以获取"city1,1223"和嵌套strtok_r获得"city1""1223"。在第二个城市之后,嵌套的标记将与父分隔符(now sTok=243;city3)一起显示。

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

#define MAX_CITIES 120

typedef struct {
    char *name;
    int distance;
} location_s;

int main(void) 
{
    char *str = "city1,1223;city2,243;city3,500;city4,50";
    char *delim = ";";
    char *subDelim = ",";

    char *endStr;
    char *tok, *buf;

    location_s *loc[MAX_CITIES];

    /* Work around str* str[] conversion */
    buf = malloc(strlen(str));
    strcpy(buf, str);

    tok = strtok_r(buf, delim, &endStr);

    int tokenCount = 0, subTokenCount = 0;
    while (tok) {
        char *lastToken;
        char *sTok = strtok_r(tok, subDelim, &lastToken);
        loc[tokenCount] = (location_s*)malloc(sizeof(location_s));
        while(sTok){
            printf("now sTok=%s\n",sTok);
            if(subTokenCount == 0) loc[tokenCount]->name     = sTok;
            if(subTokenCount == 1) loc[tokenCount]->distance = atoi(sTok);

            subTokenCount++;
            sTok = strtok_r(NULL, subDelim, &lastToken);
        }
        subTokenCount = 0;
        tokenCount++;
        tok = strtok_r(NULL, "\n", &endStr);
    }

    /* Iterating through list of location */
    int minDistance = INT_MAX;
    int refPoint = 0, j = 0;
    int refDistance = minDistance - refPoint;
    char *minCity;
    for(int i=0; i < tokenCount; i++) {
        refDistance = loc[i]->distance - refPoint;
        if (refDistance < minDistance) {
            minDistance = loc[i]->distance;
            j = i;
        }
    }

    minCity = malloc(sizeof(loc[j]->name));
    strcpy(minCity, loc[j]->name);

    printf("min: %d", minDistance);
    printf("\nplace: %s", minCity);
    free(minCity);
    free(buf);

    return 0;
}

我知道strtok不是一个可行的解决方案,因为它会丢失先前令牌的上下文,这里是终端的输出。

$ ./a.exe
now sTok=city1
now sTok=1223
now sTok=city2
now sTok=243;city3
now sTok=500;city4
now sTok=50
min: 243
place: city2

1 个答案:

答案 0 :(得分:0)

这项工作,如克里斯指出,有一个错字

  

看起来代码正在按照您的要求进行操作,并且您在tok = strtok_r中输入了拼写错误(NULL,&#34; \ n&#34;,&amp; endStr);应该是tok = strtok_r(NULL,delim,&amp; endStr); - 克里斯特纳

现在输出如下:

$ ./a.exe
now sTok=city1
now sTok=1223
now sTok=city2
now sTok=243
now sTok=city3
now sTok=500
now sTok=city4
now sTok=50
min: 50
place: city4