जवाबों:
बस अंतिम 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;
}
इस फ़ंक्शन का उपयोग करें:
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());
}
std::equal(suffix.rbegin(), suffix.rend(), str.rbegin()
डीबग मोड में, यह फेंकता है:_DEBUG_ERROR("string iterator not decrementable");
उपयोग करें 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));
ध्यान दें, कि c ++ 20 std :: string से शुरू होकर अंत में start_with और end_with प्रदान करेगा । ऐसा लगता है कि एक मौका है कि c ++ में c ++ के 30 तार अंत में प्रयोग करने योग्य हो सकते हैं, यदि आप इसे दूर के भविष्य से नहीं पढ़ रहे हैं, तो आप इन का उपयोग कर सकते हैं।
#include <string>
static bool endsWith(const std::string& str, const std::string& suffix)
{
return str.size() >= suffix.size() && 0 == str.compare(str.size()-suffix.size(), suffix.size(), suffix);
}
static bool startsWith(const std::string& str, const std::string& prefix)
{
return str.size() >= prefix.size() && 0 == str.compare(0, prefix.size(), prefix);
}
और कुछ अतिरिक्त सहायक अधिभार:
static bool endsWith(const std::string& str, const char* suffix, unsigned suffixLen)
{
return str.size() >= suffixLen && 0 == str.compare(str.size()-suffixLen, suffixLen, suffix, suffixLen);
}
static bool endsWith(const std::string& str, const char* suffix)
{
return endsWith(str, suffix, std::string::traits_type::length(suffix));
}
static bool startsWith(const std::string& str, const char* prefix, unsigned prefixLen)
{
return str.size() >= prefixLen && 0 == str.compare(0, prefixLen, prefix, prefixLen);
}
static bool startsWith(const std::string& str, const char* prefix)
{
return startsWith(str, prefix, std::string::traits_type::length(prefix));
}
IMO, c ++ स्ट्रिंग्स स्पष्ट रूप से बेकार हैं, और वास्तविक विश्व कोड में उपयोग करने के लिए नहीं बनाए गए थे। लेकिन एक उम्मीद है कि यह कम से कम बेहतर हो जाएगा।
मैं C ++ के लिए प्रश्न जानता हूं, लेकिन अगर किसी को ऐसा करने के लिए एक अच्छे ol 'फ़ैशन सी फ़ंक्शन की आवश्यकता है:
/* 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 );
}
यह 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() );
std::equal
: आपको पहले से जांचने की आवश्यकता है कि माना गया प्रत्यय उस स्ट्रिंग से अधिक लंबा नहीं है जिसे आप इसके लिए खोज रहे हैं। यह जांचने के लिए उपेक्षा करना कि अपरिभाषित व्यवहार की ओर जाता है।
मेरी राय में सबसे सरल, C ++ समाधान है:
bool endsWith(const string& s, const string& suffix)
{
return s.rfind(suffix) == std::abs(s.size()-suffix.size());
}
s
इसके अंत के परीक्षण के बजाय पूरे स्ट्रिंग को खोज लेंगे !
std::string::size()
एक निरंतर-समय ऑपरेशन है; इसकी जरूरत नहीं है strlen
।
चलो a
देना एक स्ट्रिंग और b
स्ट्रिंग आप के लिए देखो। a.substr
के अंतिम n अक्षर प्राप्त करने के लिए उपयोग करें a
और उनकी तुलना b से करें (जहाँ n की लंबाई है b
)
या उपयोग 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());
}
केस असंवेदनशील संस्करण ( ऑनलाइन डेमो ) के साथ मुझे यूसुफ के समाधान का विस्तार करने दें
static bool EndsWithCaseInsensitive(const std::string& value, const std::string& ending) {
if (ending.size() > value.size()) {
return false;
}
return std::equal(ending.rbegin(), ending.rend(), value.rbegin(),
[](const char a, const char b) {
return tolower(a) == tolower(b);
}
);
}
ऊपर के रूप में ही, यहाँ मेरा समाधान है
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());
}
starts_with
स्ट्रिंग :: तुलना ’का उपयोग क्यों करता है? क्यों नहीं std::equal(start.begin(), start.end(), str.begin())
?
एक और विकल्प रेगेक्स का उपयोग करना है। निम्न कोड ऊपरी / निचले मामले में खोज को असंवेदनशील बनाता है:
bool endsWithIgnoreCase(const std::string& str, const std::string& suffix) {
return std::regex_search(str,
std::regex(std::string(suffix) + "$", std::regex_constants::icase));
}
शायद इतना कुशल नहीं है, लेकिन इसे लागू करना आसान है।
आप स्ट्रिंग का उपयोग कर सकते हैं :: 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;
}
पता लगाएं कि str है प्रत्यय , नीचे का उपयोग कर:
/*
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;
}
एसटीडी का उपयोग करें <algorithms>
: रिवर्स इटर्शन से समान एल्गोरिथ्म :
std::string LogExt = ".log";
if (std::equal(LogExt.rbegin(), LogExt.rend(), filename.rbegin())) {
…
}
ग्रेज़गोरज़ बाज़ीर की प्रतिक्रिया के बारे में। मैंने इस कार्यान्वयन का उपयोग किया, लेकिन मूल में बग है (यदि मैं ".." के साथ ".so") की तुलना में सही है (तो सही है)। मैं संशोधित कार्य प्रस्तावित करता हूं:
bool endsWith(const string& s, const string& suffix)
{
return s.size() >= suffix.size() && s.rfind(suffix) == (s.size()-suffix.size());
}
मैंने सोचा कि यह एक कच्चे समाधान पोस्ट करने के लिए समझ में आता है जो किसी भी पुस्तकालय कार्यों का उपयोग नहीं करता है ...
// 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;
}
इस तरह के "startWith" के लिए यह अच्छा जवाब मिला -प्रोफ़ाइल:
आप स्ट्रिंग में अंतिम स्थान पर केवल खोज करने के लिए समाधान को अपना सकते हैं:
bool endsWith(const std::string& stack, const std::string& needle) {
return stack.find(needle, stack.size() - needle.size()) != std::string::npos;
}
इस तरह से आप इसे छोटा, तेज, मानक c ++ का उपयोग कर सकते हैं और इसे पठनीय बना सकते हैं।
यदि आप मेरे जैसे हैं और 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;
}