@MatthieuM. Ваш пример сбивает с толку, я думаю, что суть вопроса в том, чтобы изменить исходную строку, в вашем примере вы не изменяете исходную строку, потому что в вашем примере исходная строка называется «myString», что приводит к путанице, в вопросе это "ул". Ваш код должен быть: st = st.substr(0, st.size()-1). Но она по- прежнему не выглядит правильно, я думаю , что правильный способ заключается в использовании функции , которая предназначена для решения этой задачи, она называется Стирание () и код: st.erase(st.size()-1). Это будет называться "мутантной версией".
Чаре Томчак
1
@CzarekTomczak: я понимаю, что это не совсем то, о чем просили, таким образом, отказ от ответственности перед фактической сущностью.
Матье М.
2
@MattPhillips: его решение специфично для C ++ 11 ( pop_backне существовало в C ++ 03), и это также модификация на месте (и ОП никогда не уточнял, хочет ли он на месте или нет) ... как Таким образом , он имеет более правильный ответ, но не возможно только один.
Матье М.
404
Простое решение, если вы используете C ++ 11. Вероятно, O (1) время:
Нет std::string::pop_backв C ++ 03; это было добавлено в C ++ 0x, хотя.
Джеймс МакНеллис
Хорошо, спасибо. Это вызвало некоторую путаницу - я могу поклясться, что использовал это, но его там нет. Возможно, у меня где-то есть нестандартная библиотека в каком-то компиляторе (между VC ++ 2003, VC ++ 2008, MinGW GCC3, MinGW GCC 4 и Linux GCC 4, у вас есть несколько отличий). Скорее всего, я просто путаюсь с другими типами.
Steve314
resize (), вероятно, не предназначен для такого использования, это функция, связанная с памятью, erase () предназначена для удаления символов.
Чаре Томчак
3
@Czarek Tomczak - извините за абсурдно поздний ответ, но resizeэто функция изменения размера, и больше не функция памяти, как все, что может увеличить необходимую память. Например, если вы resizeуменьшите размер, это не уменьшит зарезервированную память. Я думаю, вы думаете о том reserve, что, по крайней мере, может уменьшить объем выделяемой памяти, если будет предложено - см. Здесь изменить размер и зарезервировать здесь .
Steve314
3
if (! str.empty ()) предпочтительнее размера
ericcurtin
19
buf.erase(buf.size()-1);
Это предполагает, что вы знаете, что строка не пуста. Если это так, вы получите out_of_rangeисключение.
buf [buf.size () - 1] = '\ 0'; ничего не удаляет - он просто меняет символ, который был там, чтобы иметь значение ноль. std:; строки могут успешно содержать такие символы.
Нил прав. Я, наверное, должен был уточнить это в своем ответе. Второй параметр будет эффективно изменять значение последнего символа, поэтому он не будет печататься, но длина строки останется прежней. Использование erase фактически «удаляет» последний символ и изменит размер строки.
RC.
@RC Будет напечатано, если вы используете что-то вроде cout << buf. Как это будет выглядеть, будет зависеть от вашей платформы. И вы всегда можете уточнить, отредактировав свой ответ.
Что гораздо лучше о size() вместо end()другого ответа?
Это может привести к странной ситуации: размер строки был уменьшен, но последний символ не установлен в '\ 0'.
Deqing
1
@Deqing, можешь ли ты рассказать подробнее о том, что происходит в таком случае?
Рибамар
Например , если вы string s("abc");, после того, как стирают кажется работающих: cout<<s; // prints "ab", однако, последний символ еще есть: cout<<s[2]; // still prints 'c'.
Deqing
1
легко исправить: простоstr[str.length()-1] = 0; str.erase(str.end()-1);
таксист
5
@Dequing: ваш пример неверен. Стирание уменьшает размер строки, поэтому доступ к нему s[2]является незаконным.
CString str=CString("Hello world"); str.Delete(str.GetLength()-1);
Ответы:
Для версии без мутаций:
источник
st = st.substr(0, st.size()-1)
. Но она по- прежнему не выглядит правильно, я думаю , что правильный способ заключается в использовании функции , которая предназначена для решения этой задачи, она называется Стирание () и код:st.erase(st.size()-1)
. Это будет называться "мутантной версией".pop_back
не существовало в C ++ 03), и это также модификация на месте (и ОП никогда не уточнял, хочет ли он на месте или нет) ... как Таким образом , он имеет более правильный ответ, но не возможно только один.Простое решение, если вы используете C ++ 11. Вероятно, O (1) время:
источник
length()
.The behavior is undefined if the string is empty.
от сюдаАльтернатива std :: erase хороша, но мне нравится "- 1" (независимо от размера или конечного итератора) - для меня это помогает выразить намерение.
Кстати, действительно ли нет std :: string :: pop_back? - кажется странным.
источник
std::string::pop_back
в C ++ 03; это было добавлено в C ++ 0x, хотя.resize
это функция изменения размера, и больше не функция памяти, как все, что может увеличить необходимую память. Например, если выresize
уменьшите размер, это не уменьшит зарезервированную память. Я думаю, вы думаете о томreserve
, что, по крайней мере, может уменьшить объем выделяемой памяти, если будет предложено - см. Здесь изменить размер и зарезервировать здесь .Это предполагает, что вы знаете, что строка не пуста. Если это так, вы получите
out_of_range
исключение.источник
size()
вместоend()
другого ответа?str.erase( str.end()-1 )
Ссылка: std :: string :: erase () прототип 2
не требуется c ++ 11 или c ++ 0x.
источник
string s("abc");
, после того, как стирают кажется работающих:cout<<s; // prints "ab"
, однако, последний символ еще есть:cout<<s[2]; // still prints 'c'
.str[str.length()-1] = 0; str.erase(str.end()-1);
s[2]
является незаконным.Это все, что вам нужно:
источник
источник
С C ++ 11 вам даже не нужны длина / размер. Пока строка не пуста, вы можете сделать следующее:
источник
str.erase(str.begin() + str.size() - 1)
str.erase(str.rbegin())
не компилируется к сожалению, так какreverse_iterator
не может быть преобразован в normal_iterator.C ++ 11 в этом случае ваш друг.
источник
str.erase(str.end() - 1)
?Если длина не равна нулю, вы также можете
источник
\0
не меняет длину строки.str.length()
будет неточным.