Holen Sie sich das letzte Element eines std :: string

87

Ich habe mich gefragt, ob es eine Abkürzung oder eine elegantere Methode gibt, um das letzte Zeichen einer Zeichenfolge wie in:

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

So etwas myString.back()scheint nicht zu existieren. Gibt es ein Äquivalent?

Deve
quelle
Ich denke, es ist nicht notwendig, weil Sie das mit den bereitgestellten Funktionen ziemlich einfach tun können.
Hoàng Long
4
Dieses Argument würde auch für die Containerklassen gelten.
Deve

Antworten:

128

In C ++ 11 und höher können Sie die backMember-Funktion verwenden:

char ch = myStr.back();

In C ++ 03 std::string::backist es aufgrund eines Versehens nicht verfügbar, aber Sie können dies umgehen, indem Sie das dereferenzieren, von dem reverse_iteratorSie zurückkommen rbegin:

char ch = *myStr.rbegin();

Achten Sie in beiden Fällen darauf, dass die Zeichenfolge tatsächlich mindestens ein Zeichen enthält! Andernfalls erhalten Sie undefiniertes Verhalten , was eine schlechte Sache ist.

Hoffe das hilft!

templatetypedef
quelle
13
Eine back () Funktion wurde in C ++ 11 hinzugefügt
eddi
1
@ eddi- Danke, dass du darauf hingewiesen hast! Ich habe meine Antwort entsprechend aktualisiert.
Templatetypedef
Hinweis: Ich hatte zu zwingen g ++ zu kompilieren mit --std=c++11zur back()Verfügung steht.
JulianHarty
@ JulianHarty Das gilt für die meisten C ++ 11-Funktionen, glaube ich. :-)
Templatetypedef
22

Sie möchten wahrscheinlich zuerst die Länge der Zeichenfolge überprüfen und Folgendes tun:

if (!myStr.empty())
{
    char lastChar = *myStr.rbegin();
}
Kerri Brown
quelle
2
Sie müssen die Länge nicht überprüfen. Wenn es sich um die leere Zeichenfolge handelt, wird nur '\ 0' in lastChar gespeichert.
Mark Loeser
4
@ MarkLoeser: Das stimmt nicht. *myStr.end()ist nicht dasselbe wie myStr[myStr.size()]! Und selbst wenn es so wäre, myStr.rbegin()ist es äquivalent zu myStr.end()-1, was für eine leere Zeichenfolge eindeutig ungültig ist.
Leichtigkeitsrennen im Orbit
7

Sie können eine Funktionsvorlage schreiben back, die für normale Container an die Elementfunktion delegiert, und eine normale Funktion, die die fehlende Funktionalität für Zeichenfolgen implementiert:

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

Dann können Sie einfach sagen, back(foo)ohne sich darum zu kümmern, ob fooes sich um eine Zeichenfolge oder einen Vektor handelt.

Fredoverflow
quelle
2

*(myString.end() - 1)vielleicht? Das ist auch nicht gerade elegant.

Ein Python-Esque myString.at(-1)würde zu viel von einer bereits aufgeblähten Klasse verlangen.

Tenpn
quelle