在c++中,如何知道字符串是否以另一个字符串结束?


当前回答

std::mismatch方法可以用于从两个字符串的末尾开始向后迭代:

const string sNoFruit = "ThisOneEndsOnNothingMuchFruitLike";
const string sOrange = "ThisOneEndsOnOrange";

const string sPattern = "Orange";

assert( mismatch( sPattern.rbegin(), sPattern.rend(), sNoFruit.rbegin() )
          .first != sPattern.rend() );

assert( mismatch( sPattern.rbegin(), sPattern.rend(), sOrange.rbegin() )
          .first == sPattern.rend() );

其他回答

在我看来,最简单的c++解决方案是:

bool endsWith(const std::string& s, const std::string& suffix)
{
    return s.rfind(suffix) == std::abs(s.size()-suffix.size());
}

警告:如果匹配失败,这将在放弃之前向后搜索整个字符串,从而可能浪费大量循环。

如果你像我一样,对c++的纯粹主义不那么感兴趣,这里有一个古老的混合体。当字符串多于几个字符时,会有一些优势,因为大多数memcmp实现都尽可能比较机器单词。

你需要控制字符集。例如,如果这种方法与utf-8或wchar类型一起使用,则会有一些缺点,因为它不支持字符映射——例如,当两个或多个字符在逻辑上相同时。

bool starts_with(std::string const & value, std::string const & prefix)
{
    size_t valueSize = value.size();
    size_t prefixSize = prefix.size();

    if (prefixSize > valueSize)
    {
        return false;
    }

    return memcmp(value.data(), prefix.data(), prefixSize) == 0;
}


bool ends_with(std::string const & value, std::string const & suffix)
{
    size_t valueSize = value.size();
    size_t suffixSize = suffix.size();

    if (suffixSize > valueSize)
    {
        return false;
    }

    const char * valuePtr = value.data() + valueSize - suffixSize;

    return memcmp(valuePtr, suffix.data(), suffixSize) == 0;
}

我的观点是:

bool endsWith(std::string str, std::string suffix)
{
   return str.find(suffix, str.size() - suffix.size()) != string::npos;
}

如果像我一样,你需要endsWith来检查文件扩展名,你可以使用std::filesystem库:

std::filesystem::path("/foo/bar.txt").extension() == ".txt"
bool endswith(const std::string &str, const std::string &suffix)
{
    string::size_type totalSize = str.size();
    string::size_type suffixSize = suffix.size();

    if(totalSize < suffixSize) {
        return false;
    }

    return str.compare(totalSize - suffixSize, suffixSize, suffix) == 0;
}