326

文字列がC++で別の文字列で終わっているかどうかを調べるにはどうすればよいですか?

4

22 に答える 22

240

次を使用して、最後のn文字を比較するだけstd::string::compareです。

#include <iostream>

bool hasEnding (std::string const &fullString, std::string const &ending) {
    if (fullString.length() >= ending.length()) {
        return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
    } else {
        return false;
    }
}

int main () {
    std::string test1 = "binary";
    std::string test2 = "unary";
    std::string test3 = "tertiary";
    std::string test4 = "ry";
    std::string ending = "nary";

    std::cout << hasEnding (test1, ending) << std::endl;
    std::cout << hasEnding (test2, ending) << std::endl;
    std::cout << hasEnding (test3, ending) << std::endl;
    std::cout << hasEnding (test4, ending) << std::endl;

    return 0;
}
于 2009-05-17T08:34:04.790 に答える
198

この関数を使用します。

inline bool ends_with(std::string const & value, std::string const & ending)
{
    if (ending.size() > value.size()) return false;
    return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
}
于 2010-01-15T15:59:34.780 に答える
168

使用しますboost::algorithm::ends_with(例: http://www.boost.org/doc/libs/1_34_0/doc/html/boost/algorithm/ends_with.htmlを参照):

#include <boost/algorithm/string/predicate.hpp>

// works with const char* 
assert(boost::algorithm::ends_with("mystring", "ing"));

// also works with std::string
std::string haystack("mystring");
std::string needle("ing");
assert(boost::algorithm::ends_with(haystack, needle));

std::string haystack2("ng");
assert(! boost::algorithm::ends_with(haystack2, needle));
于 2011-06-12T21:36:04.233 に答える
44

C ++に関する質問であることは知っていますが、これを行うために古き良きC関数が必要な場合:


/*  returns 1 iff str ends with suffix  */
int str_ends_with(const char * str, const char * suffix) {

  if( str == NULL || suffix == NULL )
    return 0;

  size_t str_len = strlen(str);
  size_t suffix_len = strlen(suffix);

  if(suffix_len > str_len)
    return 0;

  return 0 == strncmp( str + str_len - suffix_len, suffix, suffix_len );
}

于 2011-10-10T20:22:14.833 に答える
26

この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() );
于 2009-05-18T08:12:09.333 に答える
18

私の意見では、最も単純な C++ ソリューションは次のとおりです。

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

警告:一致が失敗した場合、これはあきらめる前に文字列全体を逆方向に検索するため、多くのサイクルが無駄になる可能性があります。

于 2013-09-08T06:59:46.337 に答える
11

文字列とあなたが探している文字a列をしましょう。の最後の n 文字を取得し、それらを b と比較するためにb使用します(n は の長さです) 。a.substrab

または使用std::equal(インクルード<algorithm>)

元:

bool EndsWith(const string& a, const string& b) {
    if (b.size() > a.size()) return false;
    return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin());
}
于 2009-05-17T08:27:09.533 に答える
7

大文字と小文字を区別しないバージョンでジョセフのソリューションを拡張させてください(オンラインデモ

#include <string>
#include <cctype>

static bool EndsWithCaseInsensitive(const std::string& value, const std::string& ending) {
    if (ending.size() > value.size()) {
        return false;
    }
    return std::equal(ending.crbegin(), ending.crend(), value.crbegin(),
        [](const unsigned char a, const unsigned char b) {
            return std::tolower(a) == std::tolower(b);
        }
    );
}
于 2018-01-03T22:27:31.287 に答える
4

string::rfindを使用できます

コメントに基づく完全な例:

bool EndsWith(string &str, string& key)
{
size_t keylen = key.length();
size_t strlen = str.length();

if(keylen =< strlen)
    return string::npos != str.rfind(key,strlen - keylen, keylen);
else return false;
}
于 2009-05-17T08:38:51.813 に答える
3

上記とまったく同じ、これが私の解決策です

 template<typename TString>
  inline bool starts_with(const TString& str, const TString& start) {
    if (start.size() > str.size()) return false;
    return str.compare(0, start.size(), start) == 0;
  }
  template<typename TString>
  inline bool ends_with(const TString& str, const TString& end) {
    if (end.size() > str.size()) return false;
    return std::equal(end.rbegin(), end.rend(), str.rbegin());
  }
于 2016-03-01T22:46:54.483 に答える
3

以下を使用して、strsuffixがあるかどうかを確認します。

/*
Check string is end with extension/suffix
*/
int strEndWith(char* str, const char* suffix)
{
  size_t strLen = strlen(str);
  size_t suffixLen = strlen(suffix);
  if (suffixLen <= strLen) {
    return strncmp(str + strLen - suffixLen, suffix, suffixLen) == 0;
  }
  return 0;
}
于 2016-12-02T08:41:29.370 に答える
1

ライブラリ関数を使用しない生のソリューションを投稿するのは理にかなっていると思いました...

// Checks whether `str' ends with `suffix'
bool endsWith(const std::string& str, const std::string& suffix) {
    if (&suffix == &str) return true; // str and suffix are the same string
    if (suffix.length() > str.length()) return false;
    size_t delta = str.length() - suffix.length();
    for (size_t i = 0; i < suffix.length(); ++i) {
        if (suffix[i] != str[delta + i]) return false;
    }
    return true;
}

単純なものを追加すると、std::tolowerこの大文字と小文字を区別しないようにすることができます

// Checks whether `str' ends with `suffix' ignoring case
bool endsWithIgnoreCase(const std::string& str, const std::string& suffix) {
    if (&suffix == &str) return true; // str and suffix are the same string
    if (suffix.length() > str.length()) return false;
    size_t delta = str.length() - suffix.length();
    for (size_t i = 0; i < suffix.length(); ++i) {
        if (std::tolower(suffix[i]) != std::tolower(str[delta + i])) return false;
    }
    return true;
}
于 2016-12-08T14:10:28.487 に答える
1

別のオプションは、正規表現を使用することです。次のコードは、大文字/小文字を区別しない検索を行います。

bool endsWithIgnoreCase(const std::string& str, const std::string& suffix) {
  return std::regex_search(str,
     std::regex(std::string(suffix) + "$", std::regex_constants::icase));
}

おそらくそれほど効率的ではありませんが、実装は簡単です。

于 2019-01-30T22:52:54.830 に答える
1

私のように、ファイル拡張子を確認するために endWith が必要な場合は、次のstd::filesystemライブラリを使用できます。

std::filesystem::path("/foo/bar.txt").extension() == ".txt"
于 2021-03-25T17:01:56.250 に答える
0
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;
}
于 2020-09-10T08:02:11.357 に答える