Obtenha o último elemento de uma std :: string

87

Eu queria saber se existe uma abreviatura ou uma maneira mais elegante de obter o último caractere de uma string como em:

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

Algo parecido com myString.back()não parece existir. Existe um equivalente?

Deve
fonte
Acho que não é necessário, porque você pode fazer isso facilmente com as funções fornecidas.
Hoàng Long
4
Esse argumento seria válido para as classes de contêiner também.
Deve

Respostas:

129

No C ++ 11 e posterior, você pode usar a backfunção de membro:

char ch = myStr.back();

Em C ++ 03, std::string::backnão está disponível devido a um descuido, mas você pode contornar isso desreferenciando o que reverse_iteratorvocê obteve de volta rbegin:

char ch = *myStr.rbegin();

Em ambos os casos, tenha o cuidado de se certificar de que a string tem pelo menos um caráter! Caso contrário, você obterá um comportamento indefinido , o que é uma coisa ruim.

Espero que isto ajude!

templatetypedef
fonte
13
uma função back () foi adicionada em C ++ 11
eddi
1
@ eddi- Obrigado por apontar isso! Eu atualizei minha resposta de acordo.
templatetypedef de
Nota: Eu tive que forçar g ++ para compilação com --std=c++11para back()estar disponível.
JulianHarty
@JulianHarty Isso é verdade para a maioria dos recursos do C ++ 11, eu acredito. :-)
templatetypedef
22

Você provavelmente deseja verificar o comprimento da string primeiro e fazer algo assim:

if (!myStr.empty())
{
    char lastChar = *myStr.rbegin();
}
Kerri Brown
fonte
2
Você não precisa verificar o comprimento. Se for uma string vazia, você apenas obtém '\ 0' armazenado em lastChar.
Mark Loeser de
4
@MarkLoeser: Isso não é verdade. *myStr.end()não é o mesmo que myStr[myStr.size()]! E, mesmo se fosse, myStr.rbegin()é equivalente a myStr.end()-1, que é claramente inválido em uma string vazia.
Lightness Races in Orbit
7

Você pode escrever um modelo de função backque delega a função de membro para contêineres comuns e uma função normal que implementa a funcionalidade ausente para strings:

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

Então você pode simplesmente dizer back(foo)sem se preocupar se fooé uma string ou um vetor.

fredoverflow
fonte
2

*(myString.end() - 1)talvez? Isso também não é exatamente elegante.

Um python-esque myString.at(-1)seria pedir muito de uma classe já inchada.

tenpn
fonte