Linux C 中的 strtok_r 和 strtok_s 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9021502/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the difference between strtok_r and strtok_s in C?
提问by petranaya
I'm trying to use this function in a C program that needs to be able to compile in Linux and Windows. At first I tried using strtok_r, but then when I compiled on windows, it complained about the function not existing and said it would assume it's an extern function, but then failed. I then used strtok_s and it compiled! Then I tried on Linux but now it's complaining that there is an "undefined reference to 'strtok_s'".
我正在尝试在需要能够在 Linux 和 Windows 中编译的 C 程序中使用此函数。起初我尝试使用 strtok_r,但是当我在 Windows 上编译时,它抱怨该函数不存在并说它会假设它是一个外部函数,但后来失败了。然后我使用 strtok_s 并编译!然后我在 Linux 上尝试,但现在它抱怨有一个“对'strtok_s'的未定义引用”。
Is one a windows only function and the other a linux function??? What can I do to make it compile on both?
一个是windows唯一的函数,另一个是linux函数???我该怎么做才能让它在两者上编译?
采纳答案by R.. GitHub STOP HELPING ICE
Both of these functions are really ugly, unintuitive idioms for parsing strings, and usually fail to meet your particular application's requirements in subtle ways. Even moreso for the plain strtok
in standard C. Just throw them out and write your own code to iterate over the char
array and break it up as needed. strchr
, strspn
, and strcspn
can be helpful in doing this or you can just work from scratch on the array.
这两个函数对于解析字符串来说都是非常丑陋、不直观的习惯用法,并且通常无法以微妙的方式满足特定应用程序的要求。对于strtok
标准 C 中的普通代码更是如此。只需将它们扔掉并编写自己的代码来迭代char
数组并根据需要将其分解。strchr
, strspn
, 并且strcspn
可以帮助执行此操作,或者您可以从头开始处理阵列。
回答by Martin Beckett
strtok_r is a thread safe version of strtok on POSIX systems
strtok_r 是 POSIX 系统上 strtok 的线程安全版本
strtok_sis a buffer overrun safe version of strtok on Windows. The standard strtok on windows is thread safe, so strtok_s should be.
strtok_s是 Windows 上 strtok 的缓冲区溢出安全版本。Windows 上的标准 strtok 是线程安全的,所以 strtok_s 应该是。
回答by Some programmer dude
strtok_s
is simply the Windows version of strtok_r
which is standard everywhere else.
strtok_s
只是 Windows 版本,strtok_r
在其他任何地方都是标准的。
One (common I would think) way to make a program portable when it comes to functions like strtok_s
/strtok_r
is to use the preprocessor:
当涉及到strtok_s
/ 之类的功能时,使程序可移植的一种(我认为很常见)方法strtok_r
是使用预处理器:
#if defined(_WIN32) || defined(_WIN64)
/* We are on Windows */
# define strtok_r strtok_s
#endif
As the prototypes and functionality is the same, you can now use only strtok_r
.
由于原型和功能相同,您现在只能使用strtok_r
.
回答by BeReal82
I don't have enough reputation to comment on other answers, so I'll have to provide my own.
我没有足够的声誉来评论其他答案,所以我必须提供我自己的。
1) To address this statement:
1) 要解决此声明:
"strtok_s is a buffer overrun safe version of strtok on Windows. The standard strtok on windows is thread safe..."
“strtok_s 是 Windows 上 strtok 的缓冲区溢出安全版本。Windows 上的标准 strtok 是线程安全的......”
This is not true. strtok_s is the thread safe version for the MSVC compiler. strtok is not thread safe!
这不是真的。strtok_s 是 MSVC 编译器的线程安全版本。strtok 不是线程安全的!
2) To address this statement:
2) 要解决此声明:
"This would probably break if compiling on Cygwin which reports itself as windows but has POSIX interfaces like
strtok_r
already defined."
“如果在 Cygwin 上编译,这可能会中断,Cygwin 将自身报告为 Windows,但具有
strtok_r
已定义的POSIX 接口。”
Again, not true. The difference is which compiler you use. When using Microsoft's Visual C++ compiler, MSVC, the function is strtok_s.
Another compiler, such as the GNU Compiler Collection, GCC, may use a different standard library implementation such as strtok_r
. Think compiler, not target platform, when identifying which function to use.
再次,不是真的。不同之处在于您使用的编译器。当使用微软的 Visual C++ 编译器 MSVC 时,函数是strtok_s.
另一个编译器,例如 GNU Compiler Collection,GCC,可能会使用不同的标准库实现,例如strtok_r
. 在确定要使用的函数时,请考虑编译器,而不是目标平台。
In my opinion, Joachim Pileborg's answer is the best one on this page. However, it needs a small edit:
在我看来,Joachim Pileborg 的回答是这一页上最好的回答。但是,它需要一个小的编辑:
#if defined(_WIN32) /* || defined(_WIN64) */
#define strtok_r strtok_s
#endif
Both _WIN32 and _WIN64 are predefined macros provided by the MSVC compiler. _WIN64 is defined when compiling a 64 bit target. _WIN32 is defined for both 32 and 64 bit targets. This is a compromise that Microsoft made for backwards compatibility. _WIN32 was created to specify the Win32 API. Now you should consider _WIN32 to specify Windows API -- it is not specific to a 32 bit target.
_WIN32 和 _WIN64 都是 MSVC 编译器提供的预定义宏。_WIN64 在编译 64 位目标时定义。_WIN32 是为 32 位和 64 位目标定义的。这是 Microsoft 为向后兼容性所做的妥协。_WIN32 被创建来指定 Win32 API。现在您应该考虑使用 _WIN32 来指定 Windows API——它不是特定于 32 位目标。
回答by Jamey Kirby
Just to clarify. strtok
is thread safe in Windows. strtok
uses a TLS
variable to maintain the last pointer for each thread. However, you can not use strtok
to interleave access to more than one token string per thread. strtok_r
and strtok_s
both address this interleaving problem by allowing the user to maintain the context via the third parameter. Hope this helps.
只是为了澄清。strtok
在 Windows 中是线程安全的。strtok
使用一个TLS
变量来维护每个线程的最后一个指针。但是,您不能使用strtok
交错访问每个线程多个令牌字符串。strtok_r
并且strtok_s
两者都通过允许用户通过第三个参数维护上下文来解决这个交织问题。希望这可以帮助。
回答by Victor
MinGW also predefines _WIN32
but it supports strtok_r
, so I don't think it is a good idea to check the _WIN32
macro. It is better to check the _MSC_VER
macro, which is the macro for Microsoft Visual Studio.
MinGW 也预定义_WIN32
但它支持strtok_r
,所以我认为检查_WIN32
宏不是一个好主意。最好检查一下_MSC_VER
宏,这是Microsoft Visual Studio 的宏。
#ifdef _MSC_VER
#define strtok_r strtok_s
#endif
WARNING: Microsoft strtok_s
and C11 strtok_s
are completely different! Microsoft strtok_s
has only 3 parameters, while C11 strtok_s
has 4 parameters, so it can be a compatible issue in the future.
警告:Microsoftstrtok_s
和 C11strtok_s
完全不同!微软strtok_s
只有3个参数,而C11strtok_s
有4个参数,所以以后可能会是兼容问题。
The prototype of Microsoft strtok_s
is
微软的原型strtok_s
是
char* strtok_s(char* str, const char* delimiters, char** context);
The prototype of C11 strtok_s
is
C11的原型strtok_s
是
char *strtok_s(char *restrict str, rsize_t *restrict strmax, const char *restrict delim, char **restrict ptr);