В чем разница между strtok r и strtok s в C?

Я пытаюсь использовать эту функцию в программе C, которая должна иметь возможность компилироваться в Linux и Windows. Сначала я попытался использовать strtok_r, но затем, когда я скомпилировал в windows, он пожаловался на несуществующую функцию и сказал, что предположит, что это функция extern, но затем не удалось. Затем я использовал strtok_s и скомпилировал его! Затем я попробовал Linux, но теперь он жалуется, что есть "неопределенная ссылка на"strtok_s"".

является одной только функцией windows, а другой функция в Linux??? Что я могу сделать, чтобы скомпилировать его на обоих?

5 ответов


обе эти функции действительно уродливые, неинтуитивные идиомы для синтаксического анализа строк и обычно не отвечают требованиям вашего конкретного приложения тонкими способами. Даже moreso на равнине strtok в стандартном C. просто выбросьте их и напишите свой собственный код для итерации по char массив и разбить его по мере необходимости. strchr, strspn и strcspn может быть полезно в этом, или вы можете просто работать с нуля на массиве.


strtok_s - это просто версия для Windows strtok_r это стандарт везде.

один (общий, Я думаю) способ сделать программу портативной, когда дело доходит до таких функций, как strtok_s/strtok_r использовать препроцессор:

#if defined(_WIN32) || defined(_WIN64)
/* We are on Windows */
# define strtok_r strtok_s
#endif

поскольку прототипы и функциональность одинаковы, теперь вы можете использовать только strtok_r.


У меня недостаточно репутации, чтобы комментировать другие ответы, поэтому мне придется предоставить свой собственный.

чтобы обратиться к этому заявлению:

" strtok_s-это безопасная версия strtok в Windows, переполненная буфером. Стандартный strtok на windows является потокобезопасным..."

Это не правда. strtok_s-это потокобезопасная версия для компилятора MSVC. что strtok не является потокобезопасным!

чтобы обратиться к этому заявлению:

"Это, вероятно, сломается, если компиляция на cygwin, которая сообщает о себе как windows, но имеет интерфейсы posix, такие как strtok_r уже определены."

опять неправда. Разница, какой компилятор вы используете. При использовании компилятора Microsoft Visual C++ MSVC функция strtok_s. Другой компилятор, такой как GNU Compiler Collection, GCC, может использовать другую стандартную реализацию библиотеки, такую как strtok_r. Думайте о компиляторе, а не о целевой платформе, определяя, какую функцию Использовать.

в моем мнение, ответ Joachim Pileborg является лучшим на этой странице. Однако для этого требуется небольшое редактирование:

#if defined(_WIN32) /* || defined(_WIN64) */
#define strtok_r strtok_s
#endif

_WIN32 и _WIN64 являются предопределенными макросами, предоставляемыми компилятором MSVC. _WIN64 определяется при компиляции 64-разрядной цели. _WIN32 определяется как для 32, так и для 64-разрядных целей. Это компромисс, который Microsoft сделала для обратной совместимости. _WIN32 был создан для указания Win32 API. Теперь вы должны рассмотреть _WIN32, чтобы указать Windows API-это не относится к 32 бит-мишень.


strtok_r-это потокобезопасная версия strtok на POSIX systems

раздел strtok_s является буфером переполнения безопасной версии strtok на Windows. Стандартный strtok в windows является потокобезопасным, поэтому strtok_s должен быть.


просто для уточнения. strtok является потокобезопасным в Windows. strtok использует переменную TLS для поддержания последнего указателя для каждого потока. Однако strtok нельзя использовать для чередования доступа к нескольким строкам токенов в потоке. strtok_r и strtok_s решают эту проблему чередования, позволяя пользователю поддерживать контекст с помощью третьего параметра. Надеюсь, это поможет.