2016-06-30 8 views
3

文字列内の2つの同じ文字の間のすべての文字を削除します。私の関数は引数で文字列(参照)とcharを取ります。文字列内の区切り文字間で文字を削除する

私はこのようなstd::string変数を使用と仮定していること:最初のパラメータと2番目のパラメータとして文字'h'として"hah haaah hah hello!"を、このような何かが起こるはず:"hah haaah hah hello!" ===> "hh hh hh hello"。ご覧のとおり、2つのh文字の間のすべての文字は削除されています。どのように私はこれのような何かを達成するのですか?私はイテレータを使用しようとしたとこれで終わってきた

void delete_chars_between(std::string& line, char del) 
{ 
    std::string::iterator itr_from = std::find(line.begin(), line.end(), del); 
    std::string::iterator itr_to = std::find(itr_from + 1, line.end(), del); 

    while (true) { 
     if(itr_to != line.end()) 
      line.erase(itr_from + 1, itr_to); 

     itr_from = std::find(itr_to, line.end(), del); 

     if (itr_from == line.end()) 
      break; 

     itr_to = std::find(itr_from + 1, line.end(), del); 

     if (itr_to == line.end()) 
      break; 
    } 
} 

まず、私がdelの最初の出現を検索し、私はitr_from内の位置に反復子を格納します。その後、私はdelの2番目の出現を検索します。最後に、itr_toが有効な場合、特定の範囲の文字を消去することから始まるwhileループを実行します。私はイテレータがline.end()と等しくない間に何度も何度も繰り返します。

何らかの理由で、このコードが正しく機能しません。空白が削除されることがあり、削除しようとしていた文字にも触れません。

ありがとうございました。

+1

['std :: regex_replace'](http://en.cppreference.com/w/cpp/regex/regex_replace)がここでより適切だろうと思います。 – NathanOliver

+0

@ NathanOliver、残念ながら正規表現の使い方はまだ分かりません。私は本当にそれを使わずに目標を達成したいと思っています。 –

+0

多分、最初のようにスペースで入力を分割するのは、次のような文字列で簡単です:http://stackoverflow.com/questions/236129/split-a-string-in-c? – duDE

答えて

3

std::stringイテレータはline.eraseへの呼び出しが未定義の動作後にそうitr_fromitr_toを使用して、文字列の長さを変更するすべての操作によって無効化されます。

while (true) { 
    if(itr_to != line.end()) 
     itr_to = line.erase(itr_from + 1, itr_to); 

    itr_from = std::find(itr_to, line.end(), del); 

    if (itr_from == line.end()) 
     break; 

    itr_to = std::find(itr_from + 1, line.end(), del); 

    if (itr_to == line.end()) 
     break; 
} 
0

あなたがeraseを呼び出す前に、両方のイテレータをリセットする必要があり未定義の動作を避けるために:

あなたはeraseの戻り値を使用する必要があります。

が期待される出力を見ると、終了の区切り文字は、別のインターバルを開始するために使用すべきではないと思われる:

void delete_chars_between(std::string& line, char del) 
{ 
    std::string::iterator itr_from = std::find(line.begin(), line.end(), del); 
    // I don't want to pass an iterator to two past the last element 
    if (itr_from == line.end()) 
     return; 
    std::string::iterator itr_to = std::find(itr_from + 1, line.end(), del); 
    //            ^^^^ 

    while (itr_to != line.end()) 
    { 
     itr_to = line.erase(itr_from + 1, itr_to); 

     itr_from = std::find(itr_to + 1, line.end(), del); 
     // to start another couple ^^^^ 
     if (itr_from == line.end()) 
      break; 

     itr_to = std::find(itr_from + 1, line.end(), del); 
    } 
} 

ライブ例HERE

"hh hh hh hello" not "hhhhhhhello" 
^^^

だから、これは私の提案です。

関連する問題