2
#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]"
4

2 回答 2

4

strtok()在其解析中具有破坏性(即它在您解析时写入您正在解析的字符串),因此它采用 achar*作为参数,而不是 a const char*

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

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

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

完成后请记住释放副本。

于 2013-05-11T09:15:13.077 回答
2

问题是c_str()返回 a const char*,因为该string对象应该是存储封装字符串的缓冲区的所有者,因此您无权修改它,除非通过string.

另一方面,strtok()接受指向 (non- const)的指针char,即 a 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命名空间的实体发生名称冲突。

于 2013-05-11T09:14:13.047 回答