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?


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!


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

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.


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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.