为什么strtok_r()只接受字符数组而不接受字符指针

时间:2018-08-17 09:35:39

标签: c++

当我尝试编译以下代码时,它可以正常编译。

char str[] = "I am Lokesh Kumar. But I liked to be called The Loki";
char *token;
char *p = str;
while (token = strtok_r(p, " ", &p)) {
    cout << token << endl;
}

但是有错误 [错误]无法将参数'3'的'char()[53]'转换为'char **'到'char * strtok_r(char *,const char *,char **)* ”  弹出以下代码

char str[] = "I am Lokesh Kumar. But I liked to be called The Loki";
char *token;
char *p = str;
while (token = strtok_r(str, " ", &str)) {
    cout << token << endl;
}

strp都保存第一个字符元素的地址,然后说明为什么出现此错误

4 个答案:

答案 0 :(得分:4)

strtok_rchar指针的地址作为其第三个参数。它将更新此指针,使其指向匹配的标记(或其他内部用法)。 str不是指针,它是char的数组,您不能将其地址传递给strtok_r,因为数组的地址与指针的地址不同。

这种困惑来自数组对象自动转换为指向其第一个元素的指针,这种指针在大多数表达式上下文(例如p = str)中使用数组时发生。

数组和指针是完全不同的东西,就像家族和个人名称一样。一个家庭( array )是一个人( characters )的集合,一个全名( pointer )指向一个人。指向字符的指针的指针类似于在纸上可以写单个人的名字(在人的意义上, character )。

这些要点也不是

  • p不需要使用第一个非strtok_r参数传递其地址到NULL之前进行初始化;
  • p不应在后续调用中作为第一个参数传递给strtok_r
  • 在条件语句中使用赋值表达式作为测试表达式被认为是较差的编码风格,您应该在赋值括号中加上明确的数值与NULL比较。

这是更正的版本:

char str[] = "I am Lokesh Kumar. But I liked to be called The Loki";
char *token;
char *arg = str;
char *p;

while ((token = strtok_r(arg, " ", &p)) != NULL) {
    printf("%s\n", token);  // using printf since you tagged the question as C
    arg = NULL;
}

答案 1 :(得分:1)

str是一个数组,p是一个指针。

不是真的
  

str和p都保存第一个字符元素的地址

真实的情况是str可转换为第一个字符的地址。但是您这样做&str是为了得到数组的地址,而不是第一个字符的地址。

由于strtok_r需要指向字符的可修改指针,因此除了声明指针变量外,别无其他方法。除非您决定将nullptr传递给第三个参数。

答案 2 :(得分:1)

p的类型为char*,因此&p的类型为char**

str的类型为char ()[53],因此&str的类型为char (*)[53]

在许多情况下,数组会衰减指向第一个元素的指针,但这不是一回事。

无论如何,您知道strtok_r的第三个参数可以以NULL开头吗?第一次调用只是输出

答案 3 :(得分:0)

这是strtok_r的通用示例用法。尽管您已经从@john answer获得了有关char数组和指针区别的详细信息。

为简单起见,我添加了此示例。我不知道为什么要让指针指向str。

您可以通过以下简单方法将字符串分隔为令牌。

有两种方法可以解决此问题。

char str[] = "I am Lokesh Kumar. But I liked to be called The Loki";
cahr *p;
char *token = strtok_r(str, " ", &p);