Использование strtok() во вложенных циклах в C?

Я пытаюсь использовать strtok() во вложенных циклах, но это не дает мне желаемых результатов, возможно, потому, что они используют одно и то же место в памяти. Мой код имеет форму: -

char *token1 = strtok(Str1, "%");
while (token1 != NULL)
{
    char *token2 = strtok(Str2, "%");
    while (token2 != NULL)
    {
        //Do something
        token2 = strtok(NULL, "%");
    }
    // Do something more
    token1 = strtok(NULL, "%");
}

person Alex Xander    schedule 02.10.2009    source источник
comment
Итак, теперь вы знаете, почему люди не используют strtok(), если они могут этого избежать. Трудно использовать правильно.   -  person Jonathan Leffler    schedule 02.10.2009


Ответы (3)


Да, strtok() действительно использует некоторую статическую память для сохранения своего контекста между вызовами. Вместо этого используйте реентерабельную версию strtok(), strtok_r() или strtok_s(), если вы используете VS (идентично strtok_r()).

У него есть дополнительный аргумент контекста, и вы можете использовать разные контексты в разных циклах.

char *tok, *saved;
for (tok = strtok_r(str, "%", &saved); tok; tok = strtok_r(NULL, "%", &saved))
{
    /* Do something with "tok" */
}
person Alex B    schedule 02.10.2009
comment
Если вы не редактируете причину, по которой strtok ведет себя таким образом, вот дополнительная информация о strtok_r: mkssoftware.com/docs/man3/strtok_r.3.asp - person Welbog; 02.10.2009
comment
Может ли кто-нибудь объяснить, как работает вышеуказанный цикл? - person MortalMan; 07.04.2015
comment
@MortalMan: этот цикл сам по себе может использовать strtok() или strtok_r() (или Microsoft strtok_s()) с минимальными изменениями для другого соглашения о вызовах strtok(). Он просто проходит через токены в str. Что отличается от использования strtok_r(), так это то, что у вас может быть внутренний цикл, также использующий strtok_r() и другую переменную вместо saved, и внутренний цикл не будет мешать внешнему циклу. Это нельзя сделать с strtok(). - person Jonathan Leffler; 06.03.2021

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

person Patrice Bernassola    schedule 02.10.2009

WayneAKing опубликовал альтернативный в Центре разработчиков Майкрософт.

Цитируя его:

Иди сюда

https://web.archive.org/web/20110305051412/http://cpp.snippets.org/code/

и скачать этот файл

stptok.c Улучшенная функция токенизации

Вы также можете скачать необходимые заголовочные файлы с того же сайта.

Это модифицированная версия strtok, которая помещает проанализированные токены (подстроки) в отдельный буфер. Вы должны быть в состоянии изменить его в соответствии с вашими потребностями.

  • Уэйн

P.S. - Обратите внимание, что эти файлы могут быть в формате *nix относительно конца строки. то есть - только 0x0A, а не 0x0D 0x0A

Это альтернатива, если в вашей среде нет библиотек Microsoft.

person SDReyes    schedule 20.05.2010