C++ strings can be declared in two main ways: as a constant pointer to chars (array-of-chars) or instantiated from the string class of the string library. Here, the pop_back() and the erase() functions are of the string object, instantiated from the string class. The last element of an array-of-chars cannot be removed because an array-of-chars is not an instantiated object.
It is true that a string literal consists of values that are characters. Each character is within an element. So the string literal actually consists of elements. The last character is removed with its last element.
This article explains how to remove the last element of a string, along with its character.
Article Content
- void pop_back()
- iterator erase(const_iterator p)
- iterator erase(const_iterator first, const_iterator last)
- basic_string& erase(size_type pos = 0, size_type n = npos)
- Conclusion
void pop_back()
This member function of the string class removes the last element of the string. The function returns void. This means that nothing is returned from it, and no variable can receive anything returned from it. The use of this function is illustrated in the following program:
#include <string>
using namespace std;
int main()
{
string str = "LMNOPQR";
cout <<str <<endl;
str.pop_back();
for (int i=0; i<str.size(); i++)
cout <<str[i];
cout <<endl;
return 0;
}
The output is:
LMNOPQ
The last character has been removed. The first two lines of the program include the necessary libraries. One of them, of course, is the string library. The string library has to be included since all strings involved are instantiated from the string class. The next line is a statement. It declares that all names below it are of the standard namespace unless otherwise indicated.
The main() function body begins with the declaration (instantiation) of the string object. The next statement displays the literal of this newly declared string at the output. The statement after removes the last character, using the pop_back() member function. The next code segment uses a for-loop with indexes to display all the characters, which no longer have the last one, in one continuous sequence.
iterator erase(const_iterator p)
If the iterator points to the last element (character), then the erase member function can remove the last element. This function returns an iterator that points to the element just after the one removed (or just after the last element, if the one removed was the last element). The following program illustrates this:
#include <string>
using namespace std;
int main()
{
string str = "LMNOPQR";
cout <<str <<endl;
string::iterator p = str.end();
p--;
string::iterator it = str.erase(p);
for (int i=0; i<str.size(); i++)
cout <<str[i];
cout <<endl;
return 0;
}
The output is:
LMNOPQ
The first three lines of the program are explained in the same way as of the previous program. In the main() function body, the first statement declares the string object. The next statement displays the literal of this newly declared string at the output. This printing could still have been done with a for-loop. The statement after obtains an iterator that points just after the last character element. This is done with the member function, end(). Note the way the iterator was declared (left-hand side of, =). Then the iterator is decremented to point to the last element.
Next, the last element is removed with the erase() member function. The next code segment uses a for-loop with indexes to display all the characters, which no longer have the last one at the terminal in one continuous sequence.
iterator erase(const_iterator first, const_iterator last)
This member function would erase a range of character elements off the string. Here, first is an iterator that points to the first element of the range. The iterator returned points to the element that was there, just after the range. If there were no elements there, it would point to the end of the string. Last is an iterator that points to the last element of the range. This last element is not involved in the erasing.
To remove the last element, the trick is to make “last”, point just beyond the last element of the string; and make the “first” point at the last element of the string. With all that, the erase function will take off the last element. The following program shows how it is done:
#include <string>
using namespace std;
int main()
{
string str = "LMNOPQR";
cout <<str <<endl;
string::iterator p = str.begin();
p = p + 6;
string::iterator q = str.end();
string::iterator it = str.erase(p, q);
for (it = --it; it >= str.begin(); it--)
cout << *it;
cout <<endl;
return 0;
}
The output is:
QPONML
After removing the character, R (together with its element), the remaining string was printed character-by-character, but in the reverse order.
The first three lines of the program are explained in the same way as of the previous program. In the main() function body, the first statement declares the string object. The next statement prints out the newly declared string.
The code segment that follows has three statements. The first one declares an iterator that points to the first character of the string. Six more characters of the string must be counted before the last character, ‘R’ is reached. So, the second statement of this segment adds 6 to the iterator. The next statement in this segment declares an iterator, q, that points just after the end of the string. The situation is now set for erasing the last element: q points just after ‘R’ and p points to ‘R’.
The statement that erases ‘R’ is:
After ‘R’ is erased, the last character becomes ‘Q’. The returned iterator, ‘it’ here, points just after ‘Q’.
The next code segment is a for-loop. The initialization statement of this for-loop simply decrements “it” to point to the new last character, ‘Q’. ‘Q’ is printed to the terminal. The for-loop continues to decrement “it”, printing the corresponding character, while ‘it’ is greater than str.begin(). When “it” is equal to str.begin(), that is, “it” is pointing to ‘L’, the for-loop prints ‘L’ and stops. In this way, the string without ‘R’ is printed in reverse order.
To obtain the value pointed to an iterator, precede the iterator with the indirection operator, * .
basic_string& erase(size_type pos = 0, size_type n = npos)
This member function erases a range, just like the above function. However, it uses indexes and not iterators. If the argument pos is 0, then the range begins from the first element. If the argument n is the length of the string (number of characters), then the range ends at the last character. Both arguments have their default values. This function returns the string class object, with the characters of the range removed.
The trick to play here is to make the value of pos the index of the last character. The index of the last character (element) is the size (length) of the list minus 1. The second argument here should be omitted for this problem. The last index is given by,
The following program, uses this member function, to take off the last character, ‘R’ from the string:
#include <string>
using namespace std;
int main()
{
string str = "LMNOPQR";
cout <<str <<endl;
int l = str.size() - 1;
string ret = str.erase(l);
for (int i = 0; i <ret.size(); i++)
cout <<str[i];
cout <<endl;
for (int i = 0; i <str.size(); i++)
cout <<str[i];
cout <<endl;
return 0;
}
The output is:
LMNOPQ
LMNOPQ
Both the original and returned string lost ‘R’. The first three lines of the program are explained in the same way as of the previous program. In the main() function body, the first statement declares the string object. The next statement prints out the newly declared string.
The next statement determines the index of the last element of the original string. The statement after erases the last character using this index. The next code segment prints out the characters of the return string, one by one, using indexes. The last code segment prints out the characters of the original string, one by one, using indexes.
Conclusion
The normal string class member function, to remove the last character of a string, with its element that holds it, is the pop_back() function. There are three erase() overloaded member functions that can also be used for this. One of them takes an iterator that points to the last character and removes the last character. Another one takes a range, indicated by two iterators: one iterator points to the last character, and the other points just after the last character. With that, the last character is taken off. The third overloaded function uses the index of the last character to remove it. All the discussion in this article has been C++20 compliant.