Pobierz ostatni element std :: string


87

Zastanawiałem się, czy istnieje skrót lub bardziej elegancki sposób uzyskania ostatniego znaku ciągu, jak w:

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

myString.back()Wydaje się, że coś takiego nie istnieje. Czy istnieje odpowiednik?


Myślę, że nie jest to konieczne, ponieważ możesz to zrobić dość łatwo dzięki dostarczonym funkcjom.
Hoàng Long

4
Ten argument będzie się odnosił również do klas kontenerów.
Deve

Odpowiedzi:


129

W C ++ 11 i nowszych możesz użyć backfunkcji składowej:

char ch = myStr.back();

W C ++ 03 std::string::backnie jest dostępny z powodu przeoczenia, ale możesz obejść ten problem, wyłuskując dane reverse_iteratorotrzymane z rbegin:

char ch = *myStr.rbegin();

W obu przypadkach upewnij się, że ciąg zawiera co najmniej jeden znak! W przeciwnym razie uzyskasz niezdefiniowane zachowanie , co jest złą rzeczą.

Mam nadzieję że to pomoże!


13
funkcja back () została dodana w C ++ 11
eddi

1
@ eddi- Dzięki za wskazanie tego! Odpowiednio zaktualizowałem moją odpowiedź.
templatetypedef

Uwaga: musiałem zmusić g ++, aby skompilować --std=c++11do back()być dostępne.
JulianHarty,

@JulianHarty To prawda dla większości funkcji C ++ 11, jak sądzę. :-)
templatetypedef

22

Prawdopodobnie chcesz najpierw sprawdzić długość ciągu i zrobić coś takiego:

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

2
Nie musisz sprawdzać długości. Jeśli jest to pusty ciąg, po prostu dostajesz '\ 0' do lastChar.
Mark Loeser,

4
@MarkLoeser: To nieprawda. *myStr.end()to nie to samo co myStr[myStr.size()]! A nawet gdyby tak było, myStr.rbegin()jest równoważne z myStr.end()-1, co jest po prostu niepoprawne w pustym łańcuchu.
Wyścigi lekkości na orbicie

7

Możesz napisać szablon funkcji, backktóry deleguje do funkcji składowej dla zwykłych kontenerów i normalną funkcję, która implementuje brakującą funkcję dla ciągów:

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

Wtedy możesz po prostu powiedzieć, back(foo)nie martwiąc się, czy foojest to ciąg, czy wektor.


2

*(myString.end() - 1)może? To też nie jest zbyt eleganckie.

Python-esque myString.at(-1)wymagałby zbyt wiele od i tak już rozdętej klasy.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.