¿Cómo puedo saber si una cadena termina con otra cadena en C++?Buscar si la cadena termina con otra cadena en C++
Respuesta
Deje a
ser una cadena y b
la cadena que busca. Utilice a.substr
para obtener los últimos n caracteres de a
y compararlos con b (donde n es la longitud de b
)
O utilice std::equal
(incluyen <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());
}
comparar simplemente el último 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;
}
puede utilizar string::rfind
El Ejemplo completo basado en los 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;
}
-1.Sí, podría usarlo, pero es innecesariamente lento en el caso de que la cadena no termine con el final proporcionado; el escaneo continuará hasta el comienzo de la cadena. Además, no mencionas que necesitas una prueba posterior para asegurarte de que el final coincide con ** al final de la cadena **, en lugar de hacerlo en otra parte de la cadena. –
Acabo de poner el enlace de la función necesaria y creo que es muy fácil hacerlo desde la documentación str.rfind (key, str.length() - key.length(), key.length()); –
OK, eso es eficiente, pero en ese caso, string :: find() funcionaría igual de bien. También debe mencionar el caso donde key.length()> str.length() - el código que sugiere en su comentario se bloqueará en este caso. Si actualiza su respuesta con esta información, dejaré mi -1. –
El método std::mismatch
puede servir a este propósito cuando se utiliza 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());
+1. Nunca antes había notado std :: mismatch(). Me pregunto qué más hay en ese archivo de encabezado de algoritmos que nunca he visto ... –
Creo que vale la pena una pregunta ASÍ: ¿alguna vez has navegado? a través de las funciones STL disponibles? – xtofl
Tenga en cuenta que esto tiene el mismo requisito que 'std :: equal': debe verificar con anticipación que el supuesto sufijo no es más largo que la cadena en la que lo está buscando. No tener en cuenta que conduce a un comportamiento indefinido. –
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());
}
@Joseph, esta es claramente la respuesta correcta. Es elegante y fiel al espíritu de C++. Edité tu respuesta con la opinión de Ahmed, pero las mentes brillantes lo rechazaron. Aquí hay un enlace a mi edición: http://stackoverflow.com/review/suggested-edits/2790894 –
Tenga en cuenta que a MSVC10 no le gusta esta solución: 'std :: equal (sufijo.rbegin(), sufijo.rend() , str.rbegin() 'En modo de depuración, arroja:' _DEBUG_ERROR ("iterador de cadena no decrementable"); ' –
Use boost::algorithm::ends_with
(consulte p. Ej. 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));
Sé que la pregunta es para C++, pero si alguien necesita un buen ol función C para hacer esto' formaron;
/* 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);
}
En mi opinión más simple, la solución C++ es:
bool endsWith(const string& s, const string& suffix)
{
return s.rfind(suffix) == (s.size()-suffix.size());
}
Esto es bastante lento ya que buscará toda la cadena' s' en lugar de simplemente probar el final de la misma ! –
@AlexisWilke ¿Lento? ¿Cuántos nanosegundos? – nodakai
@nodakai, si tengo una cadena de 1Mb, va a ser mucho más que nanosegundos. –
En cuanto a Grzegorz Bazior respuesta. Usé esta implementación, pero la original tiene errores (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());
}
el mismo que el anterior, 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());
}
¿Por qué 'starts_with' utiliza 'string :: compare'? ¿Por qué no' std :: equal (start.begin(), start.end(), str.begin()) ' ? –
Solo porque starts_with fue el primero que necesité. Ends_with se agregó más tarde. – dodjango
Comprobar si str tiene sufijo, mediante el siguiente:
/*
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;
}
Pensé que tiene sentido publicar una solución sin formato que no utiliza ninguna función de la 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 este caso 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;
}
Un montón de respuestas extrañas. Todos estos con rfind
no son buenos.La solución que usa boost/algorithm/string está bien, pero prefiero mantenerme alejado de boost. std::equal
es bueno, pero que acababa de mantener algo similar a una cuerda:
#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 cooperadoras adicionales:
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, C++ cadenas son claramente disfuncional, y no fueron hechos para ser utilizado en el código del mundo real.
Dado que str.compare no devuelve un booleano, no es tan inteligente probar "== 0" utilizando el operador not ("!"), Ya que puede ser confuso para los lectores. Utilice "... && str.compare (...) == 0" para mayor claridad. –
Si eres como yo y no tanto en el purismo C++, aquí tienes un viejo híbrido skool. Existe una ventaja cuando las cadenas son más que un puñado de caracteres, ya que la mayoría de las implementaciones de memcmp
comparan palabras de máquina cuando es posible.
Debe tener el control del juego de caracteres. Por ejemplo, si este enfoque se usa con el tipo utf-8 o wchar, existe una desventaja, ya que no admite la asignación de caracteres; por ejemplo, cuando dos o más caracteres son logically identical.
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;
}
Permítanme extender Joseph's solution con la versión de mayúsculas y minúsculas (online demo)
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);
}
);
}
- 1. Comprobando si la cadena comienza con o termina con otra cadena
- 2. ¿Cómo buscar una cadena en otra cadena?
- 3. ¿Cuál es la prueba más eficiente de si una cadena PHP termina con otra cadena?
- 4. plantillas de django, buscar cadena reemplazar con otra cadena
- 5. Buscar texto en una cadena con C#
- 6. Compruebe si una cadena termina con un número en PHP
- 7. C# buscar partido exacto en la cadena
- 8. C# Dividir una cadena por otra cadena
- 9. ¿Cómo puedo verificar si existe una cadena en otra cadena?
- 10. Encuentra una cadena dentro de otra cadena, buscar hacia atrás
- 11. Regex para probar si una cadena termina con un número
- 12. Actionscript 3: comprueba si la cadena contiene otra cadena
- 13. Compruebe si la cadena no contiene otra cadena
- 14. ¿Cómo comprobar si una cadena comienza con otra cadena en C?
- 15. std :: string comparison (compruebe si la cadena comienza con otra cadena)
- 16. búsqueda si existe una cadena en otra cadena
- 17. Compruebe si la cadena "comienza con" otra cadena en ASP clásico.
- 18. ¿Cómo puedo comprobar si una cadena termina con ".csv" en C
- 19. buscar y reemplazar la cadena
- 20. Buscar cadena en archivo de texto C
- 21. La cadena Regex termina sin funcionar en Javascript
- 22. Buscar subcadena en una cadena usando C#
- 23. Eclipse: Buscar con la cadena coincidente exacta
- 24. cadena que comienza con la extracción y termina con algo en C#
- 25. Comprobar si un elemento de la lista de Python contiene una cadena dentro de otra cadena
- 26. Reemplazar parte de una cadena con otra cadena
- 27. ¿Cómo puedo saber si una cadena comienza con otra cadena en Ruby?
- 28. Buscar subcadena en cadena pero solo si las palabras completas?
- 29. si la cadena es alfabéticamente mayor que otra cadena en el objetivo
- 30. Inserción de cadena en la posición x de otra cadena
¿Cómo puedo devolver cierto también si termina después de mi cadena con \ n o r o \ tanto ??? gracias! – sofr
@Dario: Su solución usando std :: equal() es buena, la que usa substr() no tanto, a menos que esté usando cadenas COW (y creo que pocas personas), substr() implica crear un segundo copia de una parte de la cadena, lo que implica que la asignación de memoria dinámica está involucrada. Esto puede fallar y, en cualquier caso, significa que se usa más memoria que otras soluciones (y es casi seguro que es más lenta que otras soluciones). –