正如 Jonathan Leffler 的评论所解释的,strtok 实际上修改了缓冲区以终止连续的标记。这对速度很有好处 - 无需将每个令牌复制到其他内存区域,同时仍让您可以方便地访问它作为单独的 NUL 终止序列。这是一个有趣的问题,在实例上使用 strtok 是否合法std::string
- 当然,c_str()
成员返回 aconst char*
因为您不打算覆盖该缓冲区的部分内容。但是,只要您没有空字符串(它会给出未定义的行为),您就可以char*
使用&line[0]
. 完成后,您可以改变字符串,但只能在偏移量处[0]..[size()-1]
......不能保证以 NUL 终止的方式c_str()
-returned 缓冲区是,正是因为&line[0]
-returned 缓冲区可能不适合strtok
. 您可以附加一个 NUL(即line += '\0'
- NUL 是合法std::string
内容),但它会使代码有点骇人听闻且难以维护,如果您打算将原始值用于任何事情,您可能需要在之后删除 NUL。
如果你真的想使用strtok
,似乎最好先将数据复制到一个单独的可写 NUL 终止缓冲区。例如:
char* p = strdup(line.c_str());
... use strtok on p ...
free(p);
您可以使用alloca()
智能指针 astd::vector<char>
来最大程度地减少内存泄漏的可能性。(我看不出有什么特别的理由更喜欢 C++new
和delete
上述情况——strtok
无论如何你都在使用,但如果你有智能指针库,希望它可以使用)。
综上所述,寻找另一种机制——比如 boost 中的机制——是一个更好的选择。我猜在您的问题下的评论中发布的链接克里斯中讨论了类似的替代方案....