strtok_s
je jednoduše Windows verze strtok_r
což je standard všude jinde.
Jeden (myslím běžný) způsob, jak učinit program přenositelným, pokud jde o funkce jako strtok_s
/strtok_r
je použít preprocesor:
#if defined(_WIN32) || defined(_WIN64)
/* We are on Windows */
# define strtok_r strtok_s
#endif
Protože prototypy a funkce jsou stejné, můžete nyní používat pouze strtok_r
.
Nemám dostatečnou pověst, abych mohl komentovat jiné odpovědi, takže budu muset poskytnout vlastní.
1) K tomuto prohlášení:
"strtok_s je verze strtok pro Windows bezpečná proti přetečení vyrovnávací paměti. Standardní strtok ve Windows je bezpečný pro vlákna..."
To není pravda. strtok_s je vláknově bezpečná verze pro kompilátor MSVC. strtok není bezpečný pro vlákna!
2) K tomuto prohlášení:
"To by se pravděpodobně zlomilo při kompilaci na Cygwin, který se hlásí jako okna, ale má rozhraní POSIX jako
strtok_r
již definováno."
Opět to není pravda. Rozdíl je v tom, který kompilátor používáte. Při použití kompilátoru Visual C++ společnosti Microsoft, MSVC, je funkce strtok_s.
Jiný kompilátor, jako je GNU Compiler Collection, GCC, může používat jinou implementaci standardní knihovny, jako je strtok_r
. Při určování, kterou funkci použít, myslete na kompilátor, nikoli na cílovou platformu.
Podle mého názoru je odpověď Joachima Pileborga na této stránce nejlepší. Potřebuje však malou úpravu:
#if defined(_WIN32) /* || defined(_WIN64) */
#define strtok_r strtok_s
#endif
_WIN32 i _WIN64 jsou předdefinovaná makra poskytovaná kompilátorem MSVC. _WIN64 je definován při kompilaci 64bitového cíle. _WIN32 je definován pro 32 i 64bitové cíle. Jedná se o kompromis, který Microsoft udělal pro zpětnou kompatibilitu. _WIN32 byl vytvořen k určení rozhraní API Win32. Nyní byste měli zvážit _WIN32 pro specifikaci Windows API – není specifické pro 32bitový cíl.
Obě tyto funkce jsou opravdu ošklivé, neintuitivní idiomy pro analýzu řetězců a obvykle jemnými způsoby nesplňují požadavky vaší konkrétní aplikace. Ještě více pro obyčejný strtok
ve standardním C. Stačí je vyhodit a napsat svůj vlastní kód pro iteraci přes char
pole a podle potřeby jej rozbijte. strchr
, strspn
a strcspn
může vám to pomoci, nebo můžete na poli pracovat od začátku.