当我使用不同版本的 GCC 时,为什么使用 strtok 函数会显示此错误?

Cit*_*it5 1 c++ pointers char

我有这段 C++ 代码:

const char *Delim = "some text";
char *token;
...
token = strtok('\0', Delim); // error here
Run Code Online (Sandbox Code Playgroud)

错误如下:

invalid conversion from 'char' to 'char*' [-fpermissive]
Run Code Online (Sandbox Code Playgroud)

我在 GCC 5.3 中对此进行了测试,并且有效。但是在 GCC 8.1 中它失败并给了我错误。

我知道我对 char 值进行了硬编码。但是,Delim 变量也是硬编码的。无论 GCC 版本如何,它的正确替代品是什么?为什么?

注意:我测试了以下内容以使其编译,但我想更多地了解它

const char *Delim = "some text";
char *str_0 = "\0"; // still receive warning that ISO C++ forbids converting a string constant to 'char*'
car *token;
...
token = strtok(str_0, Delim);
Run Code Online (Sandbox Code Playgroud)

有趣的是,单引号也不起作用:

const char *Delim = "some text";
char *str_0 = '\0'; // fails
car *token;
...
token = strtok(str_0, Delim);
Run Code Online (Sandbox Code Playgroud)

Ast*_*ngs 7

这是因为从 C++11 开始,char表达式'\0'不再是空指针常量(因此不再可转换为指针)。默认情况下,较新的编译器使用新版本的 C++。

您应该将实际的空指针(即nullptr,或NULL在过去)传递给该参数,而不是'\0'. 过去,您的代码之所以有效,是因为一种奇怪的隐式转换最终被删除了。这种转换可能掩盖了对传递空指针的含义的误解(这意味着“请继续之前的标记化会话”,而不是“'\0'用作分隔符”)。

所以:

token = strtok(nullptr, Delim);
Run Code Online (Sandbox Code Playgroud)

我还建议您使用-std标志告诉 GCC 您正在编写哪个版本的 C++ 。

char *str_0 = "\0"; // still receive warning that ISO C++ forbids converting a string constant to 'char*'
Run Code Online (Sandbox Code Playgroud)

长期以来,人们一直反对这种做法,近十年来一直是非法的。字符串文字应该存储在 a 中const char*,而不是 a 中char*。它们是不可变的(常量)。

无论如何,这个代码变体做了不同的事情;您现在正在对 stringstr_0进行标记,而不是继续对原始字符串进行标记。

最后,我想你可能已经把这些论点倒退了。Delim应该是分隔符列表,而不是输入字符串。如果没有您的问题的具体示例,很难确定,但"some text"它甚至看起来不像分隔符列表的占位符。

请查看一些strtok文档或您最喜欢的书中的相关部分,以刷新您对应该如何使用它的记忆。