В чем разница между 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 решают эту проблему чередования, позволяя пользователю поддерживать контекст с помощью третьего параметра. Надеюсь, это поможет.