【问题标题】:Error trying to use 'strtok' for a string尝试对字符串使用“strtok”时出错
【发布时间】:2013-05-11 09:06:32
【问题描述】:
#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]"

【问题讨论】:

  • 你应该考虑改变情节,我的意思是安娜和玛丽亚在做什么,否则这个问题会被标记为冒犯性的。

标签: c++ strtok


【解决方案1】:

strtok() 在解析过程中具有破坏性(即,它在解析时写入到您正在解析的字符串),因此它将char* 作为参数,而不是const char*.

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

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

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

完成后记得释放副本。

【讨论】:

    【解决方案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 命名空间的实体发生名称冲突。

    【讨论】:

    • 感谢您的选择;我通过添加 char *d = strdup(s.c_str()); 解决了它tok = strtok(d, " ");
    猜你喜欢
    • 1970-01-01
    • 2014-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    相关资源
    最近更新 更多