2016-08-08 65 views
0

Ich habe versucht, eine Zeichenfolge in C++ zu tokenisieren. Ich habe eine for Schleife, die ich über die Schnur zu durchlaufen bin mit, wie unten zu sehen:Ausgabe der Zeichenfolge in for Schleife ändert sich abhängig davon, ob eine bestimmte Bedingung erfüllt ist

for(unsigned int i=0; i < data_str.length(); i++) 
{ 
    tok += data_str[i]; 
    if(tok[i] == '\n') 
    { 
     //cout << "NEWLINE" << endl; 
     tok = ""; 
    } 
    if(tok == "output:") 
    { 
     cout << "OUTPUT FOUND" << endl; 
     tokens.push_back("output:"); 
     tok = ""; 
    } 
    cout << tok << endl; 
} 

Wie Sie mir Zurücksetzen den tok Variable sehen können, wenn eine bestimmte Token („output“) ist gefunden. Dann füge ich einem Vektor, den ich zum Speichern meiner Tokens verwende, eine Zeichenfolge mit der Bezeichnung tokens hinzu. Um zu sehen, ob mein Tokens-Vektor die richtige Menge an Strings hatte, habe ich ihn ausgedruckt. Ich erwartete zwei Strings, von denen jeder "output:" sagte. Wenn der Vektor jedoch gedruckt wurde, hatte er nur eine Zeichenfolge. Ich habe ein wenig Debugging durchgeführt und festgestellt, dass, wenn ich versuche, die tok Variable nach dem Finden des Tokens "output:" zurückzusetzen, die Schleife nur ein Vorkommen der Zeichenkette "output:" findet. Ich habe dann beschlossen, die tok Variable zu drucken, und bekam die folgende Ausgabe:

o 
ou 
out 
outp 
outpu 
output 
OUTPUT FOUND 

" 
"H 
"He 
"Hel 
"Hell 
"Hello 
"Hello 
"Hello W 
"Hello Wo 
"Hello Wor 
"Hello Worl 
"Hello World 
"Hello World" 
"Hello World" 

"Hello World" 
o 
"Hello World" 
ou 
"Hello World" 
out 
"Hello World" 
outp 
"Hello World" 
outpu 
"Hello World" 
output 
"Hello World" 
output: 
"Hello World" 
output:" 
"Hello World" 
output:"G 
"Hello World" 
output:"Go 
"Hello World" 
output:"Goo 
"Hello World" 
output:"Good 
"Hello World" 
output:"Goody 
"Hello World" 
output:"Goodye 
"Hello World" 
output:"Goodye 
"Hello World" 
output:"Goodye W 
"Hello World" 
output:"Goodye Wo 
"Hello World" 
output:"Goodye Wor 
"Hello World" 
output:"Goodye Worl 
"Hello World" 
output:"Goodye World 
"Hello World" 
output:"Goodye World" 
output:string 

Als ich aus der Leitung kommentierte, dass die tok Variable setze ich bekam:

o 
ou 
out 
outp 
outpu 
output 
OUTPUT FOUND 
output: 
output:" 
output:"H 
output:"He 
output:"Hel 
output:"Hell 
output:"Hello 
output:"Hello 
output:"Hello W 
output:"Hello Wo 
output:"Hello Wor 
output:"Hello Worl 
output:"Hello World 
output:"Hello World" 

o 
ou 
out 
outp 
outpu 
output 
OUTPUT FOUND 
output: 
output:" 
output:"G 
output:"Go 
output:"Goo 
output:"Good 
output:"Goody 
output:"Goodye 
output:"Goodye 
output:"Goodye W 
output:"Goodye Wo 
output:"Goodye Wor 
output:"Goodye Worl 
output:"Goodye World 
output:"Goodye World" 
output:string 
output:string 

TWhy hat meine Schleife korrekt funktionieren nur wenn ich nicht versuche, die tok Variable zurückzusetzen? Ich muss die Variable zurücksetzen, sonst funktionieren andere Teile meines Programms nicht. Gibt es eine alternative Lösung zum Zurücksetzen meiner tok Variable?

Antwort

2

Es ist offensichtlich, dass tok ein std::string ist, so:

for(unsigned int i=0; i < data_str.length(); i++) 
    { 
     tok += data_str[i]; 
     if(tok[i] == '\n') 
     { 
      //cout << "NEWLINE" << endl; 
      tok = ""; 
     } 

Verwendung von Papier und Bleistift Lassen Sie uns und folgen Sie einfach diesen Teil des Parsing-Algorithmus zusammen. Unter der Annahme, dass data_str besteht aus dem folgenden Text:

"hello\nworld" 

Nach data_str[5] zu tok hängten wird, so daß jetzt tok"hello\n" enthält, da tok[5]'\n' wird, erhält tok auf eine leere Zeichenfolge gelöscht.

Bei der nächsten Iteration wird data_str[6] zu einem leeren tok angefügt, so tok enthält nun nur ein „w“ (da es auf der vorherige Iteration der Schleife gelöscht wurde).

if(tok[i] == '\n') 

i ist jetzt 6. Dieser prüft tok[6]. Natürlich hat tok nur ein Zeichen. Dies führt zu undefiniertem Verhalten und bedeutungslosem Ergebnis.

Die Dinge gehen von diesem Punkt an ziemlich weit von den Schienen.

Wenn es die Absicht, hier ist die tok Puffer nach jedem Newline zu löschen, überprüfen Sie das letzte Zeichen von tok, die tok[tok.size()-1] wäre, statt tok[i], da i und die Größe der tok hat absolut nichts miteinander zu tun, was auch immer.

+0

Oder verwenden Sie 'data_str [i]'. – immibis