Вложенные strtok_r (): последовательные токены содержат родительский разделитель - PullRequest
0 голосов
/ 01 июня 2018

В данной строке есть ключ: пары значений городов и их расстояния, я использую strtok_r, чтобы сначала разделить, используя разделитель ";", чтобы получить "city1,1223", и вложенный strtok_r, чтобы получить "city1" и * 1006.*.После второго города появляются вложенные токены с родительским разделителем (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 голосов
/ 01 июня 2018

Выполняет работу, как указал Крис, есть опечатка

Похоже, код выполняет то, что вы просили, и у вас есть опечатка в tok = strtok_r (NULL, "\ n", & endStr);который должен быть tok = strtok_r (NULL, delim & 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...