2

我有以下程序:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) 
{
   char *tp = NULL, *cp = NULL, *next_token = NULL;
   char TokenListe[] = "Hello,I Am,1";

   tp = strtok_s(TokenListe, ", ", &next_token);

   printf(tp);
   return 0;
}

当我使用 Visual Studio 2015 编译它时,它会编译,没有任何警告。但是当我使用 Dev C++ 5.11 编译它时,我在第 10 行收到以下警告:

[警告] 赋值使指针从整数不进行强制转换

有没有解决该警告的解决方案?

4

3 回答 3

4

从 C11 开始,strtok_s现在是标准 C,是可选的“边界检查接口”(附件 K)的一部分。编译器不需要支持它。

但如果他们这样做,格式是这样的(C11 K.3.7.3.1):

#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>

char *strtok_s(char * restrict s1,
               rsize_t * restrict s1max,
               const char * restrict s2,
               char ** restrict ptr);

任何其他格式都是非标准垃圾,不应使用,包括Microsoft strtok_s

Dev C++ 不再维护,因此只包含一个非常旧的 gcc 版本。它不支持 C11,但据我所知,还没有更新版本的 gcc + 库支持 C11 边界检查接口。Visual Studio 是一个不符合标准的编译器,不能用于编译标准 C。通常,我建议不要使用这些编译器,而是更新到新版本的 gcc(例如带有 Mingw 的 Codeblocks)。

总结:strtok_s不能以合理的方式使用。改为使用strtok。只需确保所涉及的所有缓冲区都足够大并且不会溢出。在多线程程序的情况下,根本不要使用strtok

于 2018-03-02T08:50:24.427 回答
1

如果 Dev C++ 没有非标准的 strtok_s,在 C 中它将被隐式声明,并假定返回整数。

注意: strtok_s标准中,但作为“可选扩展”,根据(我的免费草稿副本)C11 标准。

您还应该启用其他警告,例如对函数隐式声明的警告。

如果 Dev C++ 确实包含 strtok_s 的实现,并与之链接,则自己声明它可能会起作用。但更好的选择是找到正确的头文件或编译器标志,以声明它(如果存在任何此类选项)。查阅文档。

但请注意,正如 Michael Walz 评论的那样,C11 标准中的 strtok_s 和 Microsoft 的 strtok_s 是不同的,并且没有相同的参数!我不知道 Dev C++ 实现了哪个版本。

于 2018-03-02T08:23:38.840 回答
0

根据@thomas-padron-mccarthy的回答,我可以通过在头文件中声明 strtok_s 函数来解决我的问题。

extern char* strtok_s(char*, char*, char**);
于 2018-03-02T08:35:42.873 回答