我对C
中的函数宏定义有疑问(我是初学者):
我有一个使用lib.a
函数的COTS库strtok()
,但是我的CERT应用程序仅支持strtok_r
,所以在编译时会出错。
如何在头文件中定义strtok
函数,以strtok_r
覆盖?
我尝试过类似的操作,但出现错误:
extern char *strtok_r(char *s1, const char *s2, char **saveptr);
#define strtok(s1,s2) strtok_r(s1,s2,saveptr)
哪种方法是达到结果的最佳而干净的方法?
非常感谢您的投入。
答案 0 :(得分:1)
假设我正确理解了你
strtok
功能。libother.a
-函数的库strtok
(只是为其命名)。Rob步入正轨,但我认为绕错了方向...
您可以通过包装strtok
函数来构建自己的strtok_r
函数:
将此功能插入您的 源文件之一:
char *strtok(char *s1, const char *delim) {
static char* saveptr = 0;
return strtok_r(s1, delim, &saveptr);
}
然后以常规方式编译和链接代码
gcc your_code_file.c -lother -o your_binary
应该做。
但是:有一个理由说明为什么您更喜欢使用strtok_r
而不是strtok
:
strtok
一次只能解析一个字符串,strtok_r
允许同时解析任意数量的不同字符串。
有了上面的“ hack”,您就失去了strtok_r
的优势。
答案 1 :(得分:0)
您不能将strtok_r重新定义为strtok,因为它们与不同数量的参数一起以不同的方式运行。
char * strtok(char * restrict,const char * restrict);
char * strtok_r(char *,const char *,char **);
如果您没有strtok_r,那么写一个就可以了。
评论员解释说,您希望从strtok_r实现strtok,所以我也包括了该代码。
这是来自WoBoq的strtok_r()
/* Reentrant string tokenizer. Generic version.
Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <string.h>
#ifndef _LIBC
/* Get specification. */
# include "strtok_r.h"
# define __strtok_r strtok_r
#endif
/* Parse S into tokens separated by characters in DELIM.
If S is NULL, the saved pointer in SAVE_PTR is used as
the next starting point. For example:
char s[] = "-abc-=-def";
char *sp;
x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def"
x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL
x = strtok_r(NULL, "=", &sp); // x = NULL
// s = "abc\0-def\0"
*/
char *
__strtok_r (char *s, const char *delim, char **save_ptr)
{
char *end;
if (s == NULL)
s = *save_ptr;
if (*s == '\0')
{
*save_ptr = s;
return NULL;
}
/* Scan leading delimiters. */
s += strspn (s, delim);
if (*s == '\0')
{
*save_ptr = s;
return NULL;
}
/* Find the end of the token. */
end = s + strcspn (s, delim);
if (*end == '\0')
{
*save_ptr = end;
return s;
}
/* Terminate the token and make *SAVE_PTR point past it. */
*end = '\0';
*save_ptr = end + 1;
return s;
}
#ifdef weak_alias
libc_hidden_def (__strtok_r)
weak_alias (__strtok_r, strtok_r)
#endif
这是来自glibc/blob/master/string/strtok.c的strtok()
/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <string.h>
/* Parse S into tokens separated by characters in DELIM.
If S is NULL, the last string strtok() was called with is
used. For example:
char s[] = "-abc-=-def";
x = strtok(s, "-"); // x = "abc"
x = strtok(NULL, "-="); // x = "def"
x = strtok(NULL, "="); // x = NULL
// s = "abc\0=-def\0"
*/
char *
strtok (char *s, const char *delim)
{
static char *olds;
return __strtok_r (s, delim, &olds);
}
这是每个函数的一个示例实现。有很多包含该库的编译器源。如果该许可证不符合您的要求,请尝试搜索另一个满足您要求的条款或编写您自己的功能。
只需将该源代码写入一个单独的文件,然后将其添加到您的链接列表中即可。
在此GeeksForGeeks网页“ strtok() and strtok_r() functions in C with examples”中解释并演示了尝试重新定义这些功能的问题。与第一次调用所提供的参数相比,strtok_r函数对后续调用的参数要求不同。用可以决定是要设置还是要测试的全局变量进行定义并不方便。