Ottieni l'ultimo elemento di uno std :: string


87

Mi chiedevo se esiste un'abbreviazione o un modo più elegante per ottenere l'ultimo carattere di una stringa come in:

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

Qualcosa di simile myString.back()sembra non esistere. C'è un equivalente?


Penso che non sia necessario, perché puoi farlo abbastanza facilmente con le funzioni fornite.
Hoàng Long

4
Questo argomento varrebbe anche per le classi contenitore.
Deve

Risposte:


129

In C ++ 11 e oltre, puoi usare la backfunzione membro:

char ch = myStr.back();

In C ++ 03, std::string::backnon è disponibile a causa di una svista, ma puoi aggirare questo problema annullando il riferimento da reverse_iteratorcui torni rbegin:

char ch = *myStr.rbegin();

In entrambi i casi, assicurati che la stringa contenga effettivamente almeno un carattere! Altrimenti, otterrai un comportamento indefinito , che è una brutta cosa.

Spero che sia di aiuto!


13
una funzione back () è stata aggiunta in C ++ 11
eddi

1
@ eddi- Grazie per averlo fatto notare! Ho aggiornato di conseguenza la mia risposta.
templatetypedef

Nota: ho dovuto forzare la compilazione con g ++ --std=c++11per back()essere disponibile.
JulianHarty

@JulianHarty Questo è vero per la maggior parte delle funzionalità di C ++ 11, credo. :-)
templatetypedef

22

Probabilmente vorrai prima controllare la lunghezza della stringa e fare qualcosa del genere:

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

2
Non devi controllare la lunghezza. Se è la stringa vuota, ottieni semplicemente "\ 0" memorizzato in lastChar.
Mark Loeser

4
@ MarkLoeser: non è vero. *myStr.end()non è lo stesso di myStr[myStr.size()]! E, anche se lo fosse, myStr.rbegin()è equivalente a myStr.end()-1, che è chiaramente non valido su una stringa vuota.
Gare di leggerezza in orbita

7

È possibile scrivere un modello di funzione backche delega alla funzione membro per contenitori ordinari e una funzione normale che implementa la funzionalità mancante per le stringhe:

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

Quindi puoi semplicemente dire back(foo)senza preoccuparti se fooè una stringa o un vettore.


2

*(myString.end() - 1)può essere? Neanche questo è esattamente elegante.

Un pitone myString.at(-1)chiederebbe troppo a una classe già gonfia.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.