2016-10-13 8 views
1

私はすべてのスペース文字を '%20'文字列に置き換えようとしています。文字列クラスに組み込みのreplace関数を使用することを考えています。string :: replaceは正しく動作しません100%時間?

現在、私が持っている:

void replaceSpace(string& s) 
{ 
    int len = s.length(); 
    string str = "%20"; 
    for(int i = 0; i < len; i++) { 
     if(s[i] == ' ') { 
      s.replace(i, 1, str); 
     } 
    } 

} 

私はアンダースコアはスペースを表す文字列 "_a_b_c_e_f_g__" に渡すと、私の出力は "%部20a%20B%20cは%の20e_f_g__" です。ここでも、アンダースコアはスペースを表します。

なぜ文字列の先頭付近のスペースが置き換えられますが、最後の方のスペースは変わっていませんか?

答えて

8

置換えごとにsを長くしていますが、ループ状態で使用されているlenは更新していません。

1

スキャンしている文字列を変更することは、足の下の枝を切断することと同じです。あなたが慎重であればうまくいくかもしれませんが、この場合、あなたはそうではありません。

つまり、最初に文字列lenを使用しますが、置換えごとに文字列が長くなり、置き換え先をさらに遠ざけてしまいます(すべてに届かないため)。

この枝をカットする正しい方法は、トランクに向けてそのエンド(先端)からです - あなたは、常に安全な足場を持ってこの方法:

void replaceSpace(string& s) 
{ 
    int len = s.length(); 
    string str = "%20"; 
    for(int i = len - 1; i >= 0; i--) { 
     if(s[i] == ' ') { 
      s.replace(i, 1, str); 
     } 
    } 

} 
0

あなたは、文字列の成長だけでその初期にループしていますサイズ。

コレクションを変更しながらループすると、エラーが発生しやすくなります。ここで

にはないソリューションです:他の人がすでに述べたように

void replace(string& s) 
{ 
    string s1; 
    std::for_each(s.begin(), 
        s.end(), 
        [&](char c) { 
         if (c == ' ') s1 += "%20"; 
         else s1 += c; 
        }); 
    s.swap(s1); 
} 
0

、問題はあなたのループの最初の文字列の長さを使用しているが、文字列が途中で大きなを取得します。あなたのループは決して文字列の終わりに達しません。

これを解決する方法はいくつかあります。ソリューションを修正し、ループを開始する前の状態ではなく、文字列の最後に移動してください。 または@molbdniloの方法を使用して、途中の文字列のコピーを作成することができます。 それとも、このようなものを使用することができます:あなたは、スペースを置き換え、このようにそれを試してみたい場合であれば

string replace_char_str(string str, string find_str, string replace_str) 
{ 
    size_t pos = 0; 
    for (pos = str.find(find_str); pos != std::string::npos; pos = str.find(find_str,pos)) 
    { 
     str.replace(pos ,1, replace_str); 
    } 
    return str; 
} 

を:ここで

std::string input = " a b c e f g "; 

std::string::size_type pos = 0; 
while ((pos = input.find(' ', pos)) != std::string::npos) 
{ 
    input.replace(pos, 1, "%20"); 
} 
0

は、それが簡単にあなたのために作ることができる機能です

string new_str = replace_char_str(yourstring, " ", "%20"); 

ご希望の場合は、こちらをご覧ください。 :)

関連する問題