Obtener el último elemento de un std :: string


87

Me preguntaba si hay una abreviatura o una forma más elegante de obtener el último carácter de una cadena como en:

char lastChar = myString.at( myString.length() - 1 );

Algo como myString.back()no parece existir. ¿Existe un equivalente?


Creo que no es necesario, porque puedes hacerlo con bastante facilidad con las funciones proporcionadas.
Hoàng Long

4
Ese argumento también se aplicaría a las clases de contenedores.
Deve

Respuestas:


129

En C ++ 11 y posteriores, puede usar la backfunción miembro:

char ch = myStr.back();

En C ++ 03, std::string::backno está disponible debido a un descuido, pero puede evitar esto eliminando la referencia de lo reverse_iteratorque obtiene rbegin:

char ch = *myStr.rbegin();

En ambos casos, asegúrese de que la cadena tenga al menos un carácter. De lo contrario, obtendrá un comportamiento indefinido , lo cual es algo malo.

¡Espero que esto ayude!


13
se ha agregado una función back () en C ++ 11
eddi

1
@ eddi- ¡Gracias por señalarlo! Actualicé mi respuesta en consecuencia.
templatetypedef

Nota: Tuve que forzar la compilación de g ++ --std=c++11para back()que estuviera disponible.
JulianHarty

@JulianHarty Eso es cierto para la mayoría de las características de C ++ 11, creo. :-)
templatetypedef

22

Probablemente desee verificar primero la longitud de la cadena y hacer algo como esto:

if (!myStr.empty())
{
    char lastChar = *myStr.rbegin();
}

2
No tienes que comprobar la longitud. Si es la cadena vacía, simplemente obtiene '\ 0' almacenado en lastChar.
Mark Loeser

4
@MarkLoeser: Eso no es cierto. *myStr.end()no es lo mismo que myStr[myStr.size()]! E, incluso si lo fuera, myStr.rbegin()es equivalente a myStr.end()-1, que es claramente inválido en una cadena vacía.
Lightness Races in Orbit

7

Podría escribir una plantilla de función backque delegue a la función miembro para contenedores ordinarios y una función normal que implemente la funcionalidad faltante para cadenas:

template <typename C>
typename C::reference back(C& container)
{
    return container.back();
}

template <typename C>
typename C::const_reference back(const C& container)
{
    return container.back();
}

char& back(std::string& str)
{
    return *(str.end() - 1);
}

char back(const std::string& str)
{
    return *(str.end() - 1);
}

Entonces puede decir back(foo)sin preocuparse si fooes una cadena o un vector.


2

*(myString.end() - 1)¿tal vez? Eso tampoco es exactamente elegante.

Un pitón-esque myString.at(-1)estaría pidiendo demasiado de una clase ya hinchada.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.