尝试将'strtok'用于字符串时出错

时间:2013-05-11 09:06:33

标签: c++ strtok

#include <iostream>
#include <string.h>
using namespace std;

int main() {
char *tok;
string s = "Ana and Maria are dancing.";
tok = strtok(s.c_str(), " ");
while(tok != NULL) {
    cout << tok << " ";
    tok = strtok(NULL, " ");
}
return 0;
}

我收到了这个错误:

:9:29: error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
In file included from ceva.cc:2:0:
348:14: error: initializing argument 1 of ‘char* strtok(char*, const char*)’ [-fpermissive]"

2 个答案:

答案 0 :(得分:4)

strtok()在解析时具有破坏性(即写入到解析时正在解析的字符串),因此需要char*作为参数,而不是const char*

c_str()返回const char*,因为它不希望您写入它返回的缓冲区的内容。

进行解析的一种方法是strdup()(即复制)你想要工作的缓冲区并解析它,即;

char* buf = strdup(s.c_str());
tok = strtok(buf, " ");
...

一旦完成,请记得免费复制。

答案 1 :(得分:2)

问题是c_str()返回const char*,因为string对象应该是存储封装字符串的缓冲区的所有者,因此您无权使用除了string的成员函数外,修改它。

另一方面,strtok()接受指向(非constchar的指针,即char*,这就是编译器抱怨的:你试图将不可修改的东西传递给想要修改那个东西的函数。

如果我可以建议一种更好的方法,这在C ++ 11中更为惯用,那么无论如何你都使用std::string,而是执行以下操作:

#include <iostream>
#include <string>

int main() 
{
    std::string s = "Ana and Maria are dancing";

    std::string::size_type start = 0;
    std::string::size_type pos = s.find(" ");
    while (pos != std::string::npos)
    {
        std::string tok = s.substr(start, pos - start);
        std::cout << tok << " ";

        start = pos + 1;
        pos = s.find(" ", start);
    }
}

上面的代码也删除了这个指令:

using namespace std;

通常认为这是错误的编程实践(特别是放在全局命名空间范围内),因为它很容易导致与属于std命名空间的实体发生名称冲突。