#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]"
答案 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()
接受指向(非const
)char
的指针,即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
命名空间的实体发生名称冲突。