几点建议:首先,您使用的
strtok
是未定义行为;在g++的情况下,甚至可能导致一些非常奇怪的行为。您不能在字符串背后修改
std::string
的内容并期望逃脱惩罚。(需要使用
const_cast
应该已经提示了您。)
其次,如果您要操作文件名,我强烈推荐使用
boost::filesystem
。它知道所有关于路径分隔符等的事情,并且路径的最后一个组件通常是特殊的(因为它可能是文件名,而不是目录)。
第三,如果这只是一次性的,或者由于其他原因您不能或不想使用Boost:
std::string::const_iterator pivot
= std::find( s.rbegin(), s.rend(), '/' ).base();
将为您提供一个迭代器,指向最后一个'/'之后的第一个字符,或者如果没有,则指向字符串中的第一个字符。之后,使用string的两个迭代器构造函数很容易获取这两个组件:
std::string basename( pivot, s.end() );
std::string dirname( s.begin(), pivot == s.begin() ? pivot : pivot - 1 );
如果您以后需要支持Windows,只需将find
替换为:
static std::string const dirSeparators( "\\/" );
std::string::const_iterator pivot
= std::find_first_of( s.rbegin(), s.rend(),
dirSeparators.begin(), dirSeparators.end() );
std::string::c_str()
的结果以去除 const。这个const char *
在任何合理的方式下都是不可修改的。因此,如果你真的需要使用strtok
,你必须进行复制。 - Evan Teran