92

I was wondering if there's an abbreviation or a more elegant way of getting the last character of a string like in:

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

Something like myString.back() doesn't seem to exist. Is there an equivalent?

2
  • I think it's not necessary, cause you can do that pretty easily with provided functions. Commented Feb 3, 2011 at 9:56
  • 4
    That argument would hold for the container classes as well.
    – Deve
    Commented Feb 3, 2011 at 10:00

4 Answers 4

142

In C++11 and beyond, you can use the back member function:

char ch = myStr.back();

In C++03, std::string::back is not available due to an oversight, but you can get around this by dereferencing the reverse_iterator you get back from rbegin:

char ch = *myStr.rbegin();

In both cases, be careful to make sure the string actually has at least one character in it! Otherwise, you'll get undefined behavior, which is a Bad Thing.

4
  • 13
    a back() function has been added in C++11
    – eddi
    Commented Mar 12, 2013 at 22:31
  • 1
    @eddi- Thanks for pointing that out! I've updated my answer accordingly. Commented Aug 20, 2013 at 21:58
  • Note: I had to force g++ to compile with --std=c++11 for back() to be available. Commented Apr 6, 2017 at 17:19
  • @JulianHarty That's true for most C++11 features, I believe. :-) Commented Apr 6, 2017 at 17:49
24

You probably want to check the length of the string first and do something like this:

if (!myStr.empty())
{
    char lastChar = *myStr.rbegin();
}
2
  • 2
    You don't have to check the length. If it is the empty string, you just get '\0' stored into lastChar. Commented Aug 20, 2013 at 22:02
  • 6
    @MarkLoeser: That is not true. *myStr.end() is not the same as myStr[myStr.size()]! And, even if it were, myStr.rbegin() is equivalent to myStr.end()-1, which is plainly invalid on an empty string. Commented Mar 10, 2015 at 22:47
7

You could write a function template back that delegates to the member function for ordinary containers and a normal function that implements the missing functionality for 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);
}

Then you can just say back(foo) without worrying whether foo is a string or a vector.

2

*(myString.end() - 1) maybe? That's not exactly elegant either.

A python-esque myString.at(-1) would be asking too much of an already-bloated class.

1
  • if string is empty it would throw Commented Jan 20, 2023 at 21:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.