Як я можу видалити останній символ із рядка C ++?
Я спробував, st = substr(st.length()-1);
але це не вийшло.
CString str=CString("Hello world"); str.Delete(str.GetLength()-1);
Як я можу видалити останній символ із рядка C ++?
Я спробував, st = substr(st.length()-1);
але це не вийшло.
CString str=CString("Hello world"); str.Delete(str.GetLength()-1);
Відповіді:
Для немутуючої версії:
st = myString.substr(0, myString.size()-1);
st = st.substr(0, st.size()-1)
. Але вона по- , як і раніше не виглядає правильно, я думаю , що правильний спосіб полягає у використанні функції , яка призначена для вирішення цього завдання, вона називається Стирання () і код: st.erase(st.size()-1)
. Це було б названо "мутаційною версією".
pop_back
не існувало в C ++ 03), і це також є модифікацією на місці (а ОП ніколи не уточнював, хотів він на місці чи ні) ... як Таким чином , він має більш правильну відповідь, але не можливо тільки один.
Просте рішення, якщо ви використовуєте C ++ 11. Можливо, O (1) час:
st.pop_back();
if (str.size () > 0) str.resize (str.size () - 1);
Альтернатива std :: стирання - це добре, але мені подобається "- 1" (на основі розміру чи кінцевого ітератора) - це допомагає виражати наміри.
BTW - Чи дійсно немає std :: string :: pop_back? - здається дивним.
std::string::pop_back
C ++ 03 немає; він доданий в C ++ 0x, хоча
resize
це функція зміни розміру, і не більше функції пам'яті, що нічого іншого, що може збільшити необхідну пам'ять. Наприклад, якщо ви resize
меншого розміру, це не зменшить зарезервовану пам'ять. Я думаю, ви думаєте про це reserve
, що принаймні може зменшити виділену пам'ять, якщо вас попросять - дивіться розмір тут і резервуйте тут .
buf.erase(buf.size() - 1);
Це передбачає, що ви знаєте, що рядок не порожній. Якщо так, ви отримаєте out_of_range
виняток.
size()
замість end()
іншої відповіді?
str.erase( str.end()-1 )
Довідка: std :: string :: прототип 2 erase ()
не потрібно 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]
нього незаконний.
int main () {
string str1="123";
string str2 = str1.substr (0,str1.length()-1);
cout<<str2; // output: 12
return 0;
}
З C ++ 11 вам навіть не потрібна довжина / розмір. Поки рядок не порожній, ви можете зробити наступне:
if (!st.empty())
st.erase(std::prev(st.end())); // Erase element referred to by iterator one
// before the end
str.erase(str.begin() + str.size() - 1)
str.erase(str.rbegin())
не компілюється, на жаль, оскільки reverse_iterator
не може бути перетворений у звичайний_тератор.
C ++ 11 - ваш друг у цьому випадку.
str.erase(str.end() - 1)
?