检查字符串是否以另一个字符串开头:find或compare?

cra*_*esh 14 c++ string stl

如果你想知道一个字符串是否以另一个字符串开头,那你将如何在C++/STL中做到这一点?在Java中String.startsWith,Python也有string.startwith,STL没有直接的方法.相反,有std::string::findstd::string::compare.到目前为止,我使用了两种方法,主要取决于我目前的心情:

if ( str1.compare( 0, str2.length(), str2 ) == 0 )
    do_something();
if ( str1.find(str2) == 0 )
    do_something();
Run Code Online (Sandbox Code Playgroud)

当然,你也可以做str.substr(0,str2.length()) == str2,也许还有其他一些方法可以达到同样的目的.find有点比较方便compare,但我看到更多人推荐compare这一点find.

但哪一个更受欢迎?有性能差异吗?它是依赖于实现的(GCC,VC++等)吗?

Ste*_*sop 14

缺点find是如果str1很长,那么它将毫无意义地一直搜索它str2.我从来没有注意到优化器足够聪明,只知道结果是否为0,并且在开始之后停止搜索str1.

缺点compare是您需要检查str2.length()不大于str1.length()(或捕获结果异常并将其视为错误结果).

令人失望的是,在标准库中最接近你想要的是std::strncmp(当然你需要使用c_str()它),因此需要boost::starts_with或你自己的等价物包括边界检查.


Foo*_*Bah 9

boost有一个算法starts_with可以相当有效地实现它:http://www.boost.org/doc/libs/1_41_0/doc/html/boost/algorithm/starts_with.html

除了标准的东西(返回值......)之外,没有关于STL实现如何必须实现查找或比较的要求,因此它完全取决于实现.


Sha*_*531 8

既然find()可能要搜索整体,string无论如何,compare()如果你想要你可以像这样包装:

#include <iostream>
#include <string>
using namespace std;

bool starts_with(const string& s1, const string& s2) {
    return s2.size() <= s1.size() && s1.compare(0, s2.size(), s2) == 0;
}

int main() {
    const string s("zipzambam");
    cout << starts_with(s, "zip") << endl;
}
Run Code Online (Sandbox Code Playgroud)