C ++文字列から最後の文字を削除する


210

C ++文字列から最後の文字を削除するにはどうすればよいですか?

試しましst = substr(st.length()-1);たがうまくいきませんでした。


6
最後の文字を削除した新しい文字列、または最後の文字を含まない同じ文字列が必要ですか?
Matthieu M.

MFC Visual C ++ CStringの場合: CString str=CString("Hello world"); str.Delete(str.GetLength()-1);
sergiol 2017年

回答:


193

非変異バージョンの場合:

st = myString.substr(0, myString.size()-1);

20
@MatthieuM。あなたの例は混乱しています、私は質問の本質は元の文字列を変更することだと思います、あなたの例では元の文字列を変更していません、あなたの例では元の文字列は混乱を与える "myString"と呼ばれるからです、質問では「st」です。コードは次のようになりますst = st.substr(0, st.size()-1)。しかし、それでも正しい方法には見えません。適切な方法は、このタスク用の関数を使用することだと思います。erase()と呼ばれ、コードは次のとおりst.erase(st.size()-1)です。これは「変更バージョン」と呼ばれます。
Czarek Tomczak 2013

1
@CzarekTomczak:私はこれが正確に要求されたものではないので、実際の要点の前の免責事項を理解しています。
Matthieu M.

2
@MattPhillips:彼の解決策はC ++ 11固有ですが(pop_backC ++ 03には存在しませんでした)、インプレース変更でもあります(OPはインプレースが必要かどうかを明確にしませんでした)...そのように、彼は正しい答えを持ってますが、唯一の可能な答えではありません。
Matthieu M. 2013

404

C ++ 11を使用している場合の簡単な解決策。おそらくO(1)時間:

st.pop_back();

49
これはc ++ 11用です!
アミール2013年

1
FYIとして-GCC 4.7からのみサポートされます(-std = c ++ 11コンパイルスイッチに沿ってオフコース)
Shmil The Cat

20
確認することを忘れないでくださいlength()

ええ、それはページの遠方に表示されます。
James Bedford

1
The behavior is undefined if the string is empty. ここ
ラフィ

24
if (str.size () > 0)  str.resize (str.size () - 1);

std :: eraseの代替案は良いですが、私は「-1」(サイズまたは終了反復子に基づく)が好きです-私には、意図を表現するのに役立ちます。

ところで、本当にstd :: string :: pop_backはありませんか?-奇妙に思えます。


11
std::string::pop_backC ++ 03にはありません。ただし、C ++ 0xで追加されました。
James McNellis、2010

OK-ありがとう。それは少し混乱を引き起こしました-私はそれを使用したと誓うことができましたが、それはありません。多分私はどこかのコンパイラに非標準のライブラリを持っています(VC ++ 2003、VC ++ 2008、MinGW GCC3 MinGW GCC 4とLinux GCC 4の間では、いくつかの違いがあります)。おそらく、他のタイプと混同しているだけです。
Steve314

resize()はおそらくそのような使用を目的としていません。これはメモリ関連の関数であり、erase()は文字を削除するためのものです。
Czarek Tomczak 2013

3
@Czarek Tomczak-ばかばかしいほど遅い返信で申し訳ありませんresizeが、サイズ変更機能であり、必要なメモリを増やす可能性のあるメモリ機能はありません。たとえば、resizeサイズを小さくしても、予約されたメモリ減りません。私はあなたが考えていると思いますreserve、少なくともここサイズ変更を参照してここ予約するように求められたら、割り当てられたメモリを減らすかもしれません
Steve314 2014年

3
(!str.empty())がサイズよりも優先される場合
ericcurtin 2018

19
buf.erase(buf.size() - 1);

これは、文字列が空でないことを前提としています。その場合、out_of_range例外が発生します。


8
buf [buf.size()-1] = '\ 0'; 何も削除しません-そこにあった文字をゼロの値に変更します。std:; stringsには、そのような文字を含めることができます。

ニールは正しいです。私はおそらく私の答えでこれを明確にすべきでした。2番目のオプションは、最後の文字の値を効果的に変更して印刷しないようにしますが、文字列の長さは変わりません。消去を使用すると、実際には最後の文字が「削除」され、文字列のサイズが変更されます。
RC。

@RC cout << bufのようなものを使用することを想定して、出力します。表示方法はプラットフォームによって異なります。そして、あなたはあなたの答えを編集することによっていつでも明確にすることができます。

別の答えのsize() 代わりに何がはるかに良いのend()ですか?
ribamar 2017

17

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

参照:std :: string :: erase()プロトタイプ2

c ++ 11やc ++ 0xは必要ありません。


1
これにより、奇妙な状況が発生する可能性があります。文字列のサイズは縮小されましたが、最後の文字が '\ 0'に設定されていません。
Deqing 2014年

1
@Deqingは、そのような場合に何が起こるかについてより詳細に説明できますか?
リバマール2014年

たとえば、を持っているstring s("abc");場合、消去後は機能しているようですが、cout<<s; // prints "ab"最後の文字はまだそこにありますcout<<s[2]; // still prints 'c'
Deqing 2014年

1
簡単に修正できます:ちょうどstr[str.length()-1] = 0; str.erase(str.end()-1);
タクシー運転士

5
@順序付け:あなたの例は無効です。消去すると文字列のサイズが小さくなるため、へのアクセスs[2]は不正になります。
EML 2015年

11

それだけで十分です。

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

if (!st.empty())
    st.pop_back();

9
int main () {

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

  cout<<str2; // output: 12

  return 0;
}

2

C ++ 11では、長さ/サイズも必要ありません。文字列が空でない限り、次のことができます。

if (!st.empty())
  st.erase(std::prev(st.end())); // Erase element referred to by iterator one
                                 // before the end

2

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

str.erase(str.rbegin())残念ながらコンパイルreverse_iteratorできません。normal_iteratorに変換できないためです。

この場合、C ++ 11はあなたの友達です。


この方法にも問題があり、最後の文字が '\ 0'に設定されていません。
Deqing 2014年

1
しない特別な理由はありstr.erase(str.end() - 1)ますか?
バレンティン

-4

長さがゼロ以外の場合、次のこともできます

str[str.length() - 1] = '\0';

4
最後の文字をに設定して\0も、文字列の長さは変わりません。str.length()不正確になります。
jww 2018年

はい、わかりました。C ++を検討しています。あなたは正しいです、それは文字列の長さを変更しません
Jan Glaser
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.