usar resueltos leer funciones ejercicios ejemplos como caracteres cadenas cadena arreglo c++ string ends-with

c++ - resueltos - leer cadena de caracteres en c



Encuentra si la cadena termina con otra cadena en C++ (15)

¿Cómo puedo encontrar si una cadena termina con otra cadena en C ++?


Compruebe si str tiene sufijo , utilizando a continuación:

/* 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; }


Deje que a sea ​​una cadena b la cadena que busca. Usa a.substr para obtener los últimos n caracteres de a y compáralos con b (donde n es la longitud de b )

O use std::equal (incluya <algorithm> )

Ex:

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()); }


El método std::mismatch puede servir para este propósito cuando se usa para iterar hacia atrás desde el final de ambas cadenas:

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() );


En mi opinión la más simple, la solución de C ++ es:

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


Lo mismo que arriba, aquí está mi solución.

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()); }


Pensé que tiene sentido publicar una solución sin formato que no use ninguna función de biblioteca ...

// 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; }

Añadiendo un simple std::tolower podemos hacer que este caso sea insensible

// 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; }


Permítame extender share con la versión que no distingue entre mayúsculas y minúsculas ( demostración en línea )

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); } ); }


Respecto a la respuesta de Grzegorz Bazior. Utilicé esta implementación, pero la original tiene un error (devuelve verdadero si comparo ".." con ".so"). Propongo función modificada:

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


Sé que la pregunta es para C ++, pero si alguien necesita una función C de moda para hacer esto:

/* 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 ); }


Si eres como yo y no eres tan puro en C ++, aquí tienes un viejo híbrido skool. Hay alguna ventaja cuando las cadenas son más que un puñado de caracteres, ya que la mayoría de memcmp implementaciones de memcmp comparan palabras de máquina cuando es posible.

Necesitas tener el control del conjunto de caracteres. Por ejemplo, si este enfoque se utiliza con utf-8 o wchar, hay algunas desventajas ya que no admite la asignación de caracteres, por ejemplo, cuando dos o más caracteres son lógicamente idénticos .

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; }


Tenga en cuenta que a partir de c++20 std :: string finalmente proporcionará starts_with y ends_with . Parece que existe la posibilidad de que para c ++ 30, las cadenas en c ++ finalmente puedan ser utilizables, si no estás leyendo esto desde un futuro lejano, puedes usar estos startsWith / endsWith:

#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); }

y algunas sobrecargas de ayudante extra:

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)); }

OMI, las cadenas c ++ son claramente disfuncionales y no fueron diseñadas para ser utilizadas en el código del mundo real. Pero hay una esperanza de que esto mejorará al menos.


Use boost::algorithm::ends_with (consulte, por ejemplo, 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));


Utilice esta función:

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()); }


puedes usar string::rfind

El ejemplo completo basado en comentarios:

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; }


Simplemente compare los últimos n caracteres usando 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; }