Передача правильного аргумента в strtok - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть строка, которую я пытаюсь разделить с помощью strtok():

"+ 2 3 \\ nln 9 \\ ln 10"

И затем я передаю \\n в качестве разделителя

    token = strtok(argv, "\\n");

    while (token)
    {
            args[index] = token;
            token = strtok(NULL, "\\n");
            index++;
    }

Первый элемент в моей таблице args - + 2 3, что здорово, однако второй - l. Кто-нибудь понимает почему? Если да, то как мне получить ln 9 в моей таблице args?

Ответы [ 2 ]

2 голосов
/ 16 апреля 2020

С strtok() manpage:

Аргумент delim указывает набор байтов, которые разделяют токены в проанализированной строке. Вызывающая сторона может указывать разные строки в delim в последовательных вызовах, которые анализируют одну и ту же строку.

Итак, в вашем коде "\\n" не является полной строкой delimiter. Вы просто говорите strtok, что разделителем является либо '\' (из-за выхода из двойного возврата) или 'n'.

Жетоны ваша строка, "+ 2 3\\nln 9\\ln 10" будет:

  1. "+ 2 3"
  2. пустая строка между \ и \ (strtok не отображает ее)
  3. пусто между \ и n (strtok не отображает его)
  4. "l"
  5. " 9"
  6. пустая строка между \ и \ (strtok не представляет)
  7. "l"
  8. " 10"

Чтобы выполнить то, что вы пытаетесь сделать, strtok не лучший выбор Возможно, я бы написал свою собственную функцию синтаксического анализа

  1. Нахождение "\\n" вхождений в исходной строке с использованием strstr()
  2. Либо копирование предыдущей строки в некоторую строку вывода, либо нулевое завершение ее на месте
1 голос
/ 16 апреля 2020

Я полностью согласен с приведенным выше ответом и предложениями Роберто и Герхарда.

В случае, если вас устраивает пользовательская реализация strtok для нескольких делимеров, вы можете использовать приведенный ниже рабочий раствор.

char *strtokm(char *str, const char *delim)
{
    static char *tok;
    static char *next;
    char *m;

    if (delim == NULL) return NULL;

    tok = (str) ? str : next;
    if (tok == NULL) return NULL;

    m = strstr(tok, delim);

    if (m) {
        next = m + strlen(delim);
        *m = '\0';
    } else {
        next = NULL;
    }

    return tok;
}
...