287

How can I remove last character from a C++ string?

I tried st = substr(st.length()-1); But it didn't work.

skazhy
  • 4,421
  • 7
  • 30
  • 32

12 Answers12

565

Simple solution if you are using C++11. Probably O(1) time as well:

st.pop_back();
user2891462
  • 3,033
  • 2
  • 32
  • 60
mpgaillard
  • 5,779
  • 2
  • 12
  • 6
260

For a non-mutating version:

st = myString.substr(0, myString.size()-1);
Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • 32
    @MatthieuM. Your example is confusing, I think that the essence of the question is to modify the original string, in your example you're not modifying the original string, because in your example the original string is called "myString" which gives to the confusion, in the question it is "st". Your code should be: `st = st.substr(0, st.size()-1)`. But it still doesn't look the right way, I think that the proper way is to use the function that is intended for this task, it's called erase() and the code is: `st.erase(st.size()-1)`. This would be called a "mutating version". – Czarek Tomczak Jan 19 '13 at 14:46
  • 3
    @CzarekTomczak: I understand this is not exactly what was asked for, thus the disclaimer before the actual gist. – Matthieu M. Jan 19 '13 at 15:05
  • 4
    @MattPhillips: his solution is C++11 specific though (`pop_back` did not exist in C++03) and it is also an in-place modification (and the OP never clarified whether he wanted in-place or not)... as such, he has **a** correct answer, but not the only possible one. – Matthieu M. May 21 '13 at 06:24
41

That's all you need:

#include <string>  //string::pop_back & string::empty

if (!st.empty())
    st.pop_back();
jcrv
  • 647
  • 7
  • 18
28
if (str.size() > 0)  str.resize(str.size() - 1);

An std::erase alternative is good, but I like the - 1 (whether based on a size or end-iterator) - to me, it helps expresses the intent.

BTW - Is there really no std::string::pop_back? - seems strange.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
  • 13
    There is no `std::string::pop_back` in C++03; it's been added in C++0x, though. – James McNellis Feb 22 '10 at 14:20
  • OK - thanks. It caused be a bit of confusion - I could swear I've used it, yet it's not there. Maybe I have a non-standard library in some compiler somewhere (between VC++2003, VC++2008, MinGW GCC3 MinGW GCC 4 and Linux GCC 4, you do get a few differences). More likely, I'm just getting confused with other types. –  Feb 22 '10 at 14:31
  • resize() is probably not intended for such use, it's a memory related function, erase() is for deleting characters. – Czarek Tomczak Jan 19 '13 at 14:36
  • 3
    @Czarek Tomczak - sorry for the absurdly late reply, but `resize` is a resizing function, and no more a memory function that anything else that might increase the memory needed. For example, if you `resize` to a smaller size, it will *not* reduce the memory reserved. I think you're thinking of `reserve`, which at least *might* reduce memory allocated if asked to - see [resize here](http://www.cplusplus.com/reference/string/string/resize/) and [reserve here](http://www.cplusplus.com/reference/string/string/reserve/). –  Mar 05 '14 at 06:53
  • 3
    if (!str.empty()) is preferred over size – ericcurtin Jul 09 '18 at 13:09
21
buf.erase(buf.size() - 1);

This assumes you know that the string is not empty. If so, you'll get an out_of_range exception.

RC.
  • 27,409
  • 9
  • 73
  • 93
  • 8
    buf[buf.size()-1] = '\0'; doesn't remove anything - it just changes the character that was there to have the value zero. std:;strings can happily contain such characters. –  Feb 22 '10 at 13:18
  • Neil is correct. I probably should have clarified this in my answer. The second option will effectively change the value of the last character so it won't print, but the string length will stay the same. Using erase actually "removes" the last character and will change the size of the string. – RC. Feb 22 '10 at 13:43
  • @RC It will print, assuming you use something like cout << buf. How it appears will depend on your platform. And you can always clarify by editing your answer. –  Feb 22 '10 at 20:04
  • What's much better about `size()` instead of `end()` of another answer? – ribamar Sep 08 '17 at 12:36
19

str.erase( str.end()-1 )

Reference: std::string::erase() prototype 2

no c++11 or c++0x needed.

MKroehnert
  • 3,637
  • 2
  • 34
  • 43
ribamar
  • 1,435
  • 1
  • 16
  • 26
  • 1
    This can lead to weird situation: the size of the string had been reduced but the last character is not set to '\0'. – Deqing Mar 18 '14 at 07:33
  • 1
    @Deqing can you give more details of what happens in such case? – ribamar Mar 26 '14 at 19:05
  • For example if you have `string s("abc");`, after erase it seems working: `cout< – Deqing Mar 27 '14 at 10:13
  • 1
    easily fixed: just `str[str.length()-1] = 0; str.erase(str.end()-1);` – taxilian Mar 19 '15 at 21:25
  • 6
    @Dequing: your example is invalid. The erase reduces the size of the string, so the access to `s[2]` is illegal. – EML Mar 29 '15 at 13:11
  • 2
    EML is correct. That's why it is important to use c_str() any time you're going to access character by character and expect a \0 terminal. The only correct way to access a std:string otherwise is with an iterator. – srm Mar 02 '16 at 17:53
13
int main () {

  string str1="123";
  string str2 = str1.substr (0,str1.length()-1);

  cout<<str2; // output: 12

  return 0;
}
codaddict
  • 445,704
  • 82
  • 492
  • 529
3

With C++11, you don't even need the length/size. As long as the string is not empty, you can do the following:

if (!st.empty())
  st.erase(std::prev(st.end())); // Erase element referred to by iterator one
                                 // before the end
Michael Goldshteyn
  • 71,784
  • 24
  • 131
  • 181
2

str.erase(str.begin() + str.size() - 1)

str.erase(str.rbegin()) does not compile unfortunately, since reverse_iterator cannot be converted to a normal_iterator.

C++11 is your friend in this case.

MKroehnert
  • 3,637
  • 2
  • 34
  • 43
Zebra
  • 29
  • 2
1

Don't worry about boundary check or empty string with ternary operator:

str.erase(str.end() - ((str.length() > 0) ? 1 : 0), str.end());

0
#include<iostream>
using namespace std;
int main(){
  string s = "Hello";// Here string length is 5 initially
  s[s.length()-1] = '\0'; //  marking the last char to be null character
  s = &s[0]; // using ampersand infront of the string with index will render a string from the index until null character discovered
  cout<<"the new length of the string "<<s + " is " <<s.length();
  return 0;
}
-8

If the length is non zero, you can also

str[str.length() - 1] = '\0';
Jan Glaser
  • 364
  • 2
  • 14
  • 8
    Setting the last character to `\0` does not change the length of the string. `str.length()` will be inaccurate. – jww Nov 05 '18 at 19:42
  • Yes, I see it now. We are considering C++. You are correct, it does not change the length of the string – Jan Glaser Apr 18 '19 at 22:47