2016-10-13 3 views
1

Ich versuche, jedes Leerzeichen durch '% 20' in einer Zeichenfolge zu ersetzen, und ich denke über die integrierte Ersetzungsfunktion für die String-Klasse.string :: Ersetzung funktioniert nicht 100% der Zeit?

Derzeit habe ich:

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); 
     } 
    } 

} 

Als ich in der Zeichenfolge "_a_b_c_e_f_g__" übergeben, wo die Unterstrichen Raum repräsentieren, meine Ausgabe ist "% 20a% 20b% 20c% 20e_f_g__". Unterstriche stellen wiederum den Raum dar.

Warum werden die Leerzeichen am Anfang der Zeichenfolge ersetzt, aber die Leerzeichen am Ende nicht?

Antwort

8

Sie machen s länger mit jedem Austausch, aber Sie aktualisieren nicht len, die im Schleifenzustand verwendet wird.

1

Das Ändern der Zeichenfolge, die Sie gerade scannen, ist wie das Abschneiden der Verzweigung unter Ihren Füßen. Es kann funktionieren, wenn Sie vorsichtig sind, aber in diesem Fall sind Sie nicht.

Nämlich, Sie nehmen am Anfang die Zeichenfolge len, aber mit jedem Ersatz wird Ihre Zeichenfolge länger und Sie schieben die Ersatzplätze weiter weg (so erreichen Sie nie alle von ihnen).

Der richtige Weg, um diesen Zweig zu schneiden von seinem Ende ist (Spitze) auf den Stamm - auf diese Weise Sie immer einen sicheren Stand haben:

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

Sie wachsen die Zeichenfolge, sondern nur in seinen ursprünglichen Looping Größe.

Das Schleifen einer Sammlung während der Bearbeitung ist sehr fehleranfällig.

Hier ist eine Lösung, die nicht der Fall ist: haben

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

Wie andere bereits erwähnt, das Problem ist, dass Sie die anfängliche Stringlänge in der Schleife verwenden, aber die Saite bekommt auf dem Weg größer. Ihre Schleife erreicht niemals das Ende der Zeichenfolge.

Sie haben mehrere Möglichkeiten, dies zu beheben. Sie können Ihre Lösung korrigieren und sicherstellen, dass Sie bis zum Ende der Zeichenfolge gehen, wie sie jetzt ist, und nicht so, wie sie vor dem Start der Schleife war. Oder Sie können @molbdnilo 's Weg verwenden, der eine Kopie der Zeichenfolge auf dem Weg erstellt. Oder Sie können etwas wie folgt verwenden:

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

Hier ist eine Funktion, die es leichter machen können:

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; 
} 

Also, wenn, wenn Sie die Räume ersetzen möchten, versuchen Sie es wie folgt aus:

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

Hoffe das hilft dir! :)

Verwandte Themen