2016-04-29 16 views
0

Hey Leute es scheint ein Fehler mit meinem Code zu sein.C++ STL verkettete Liste

Mein Hauptproblem ist mit dem Abschnitt, wo ich alle Vorkommen von ‚p‘ durch eine ‚h‘ gefolgt ändern möchten. Bei meinen Tests ändert es sich aus irgendeinem Grund in ein "q", wenn ich möchte, dass es sich in "f" ändert.

Zur Vereinfachung des Verfahren mit dem Problem ist die Leere Änderung(), in den zweiten zur Schleife.

Kann mir bitte jemand helfen?

#include <iostream> 
#include <list> 
#include <ctype.h> 
#include <fstream> 

using namespace std; 

void printList(const list<char> &myList); 
void fillList(list<char> &myList); 
void change(list <char> &myList); 

void printList(const list<char> &myList) 
{ 
    list<char>::const_iterator itr; 
    for (itr = myList.begin(); itr != myList.end(); itr++) { 
     cout <<*itr; 
    } 
    cout << '\n' << endl; 
} 

void fillList(list<char> &myList) 
{ 
    ifstream file("test.txt"); 
    string print; 
    while(file >> print){ 
     for (int i = 0; i<print.length(); i++) { 
      myList.push_back(print[i]); 
     } 
     myList.push_back(' '); 
    } 
} 

void change(list <char> &myList) 
{ 
    list<char>::iterator itr; 

    //rules are as follows 

    for (itr = myList.begin(); itr != myList.end(); itr++) { 
     if (*itr == 'w'){ 
      *itr = 'v'; 
     } 
    } 

    for (itr = myList.begin(); itr != myList.end(); itr++) { 
     if((*itr == 'p' && ++*itr == 'h')){// rule incomplete ask! 
      *itr = 'f'; 
     } 
    } 


} 

int main() 
{ 
    list<char> myList; 
    ifstream file("test.txt"); 
    const string print; 

    fillList(myList); 
    printList(myList); 

    change(myList); 
    printList(myList); 

    return 0; 
} 
+1

erstellen [MCVE], der folgendes beinhaltet nur * der Abschnitt, wo [Sie] alle Vorkommen von 'p' durch eine 'h' gefolgt ändern möchten * – user2079303

+0

Sorry, i bemerkte, dass meine Erklärung ein bisschen dumm war, ich habe es aktualisiert, um besser zu reflektieren, was ich tun soll. – TheByteMonster

+0

Ich wette '++ * itr' tut nicht, was du denkst, dass es ist. Und Sie sollten besser hoffen, dass Ihre Datei nicht mit "p" endet. – WhozCraig

Antwort

1

Der Code if((*itr == 'p' && ++*itr == 'h')) führt Folgendes aus:

  1. , wenn der Wert bei itr ist p
  2. den Wert bei itr nehmen und erhöhen es
    • p + 1 = q

, was Sie tun müssen, ist den Iterator zu erhöhen, nicht der Wert

if(*itr == 'p') { 
    if(itr == myList.end()) break; // return or do something else 
    std::list<char>::iterator itr2 = itr; 
    if(*(++itr2) == 'h') { 
     // do what you need to 
    } 
} 

Edit: Problem mit zufälligem Iterator und prüfen, ob p letztes Zeichen ist, wie in den Kommentaren darauf hingewiesen.

+1

Und wenn ''p'' ist das letzte Zeichen? (Ich würde nur die Loop-End-Bedingung ändern, um ein Element früher zu stoppen). – BoBTFish

+0

Sie abstürzen ... So kümmern, dass vielleicht mehr Logik hinzufügen, indem Sie die Auflösung, wenn sie in verschiedenen Stadien –

+0

ich, wo Sie kommen aus, in denen ich die itr um 1 erhöhen müssen, aber jetzt nichts mein Code tut, es doesn Ändere nicht einmal den 'ph'. Gibt es weitere Möglichkeiten, über dieses Problem nachzudenken? – TheByteMonster

1

Es ist, weil Sie den Zeiger Charakter wurden erhöht wird und nicht der Iterator. Sie können dies beheben, indem Sie *++itr anstelle von ++*itr

Ich habe Ihren Code geändert, können Sie leicht neue Regeln machen.

//we copy the string because we want to modify it without modifying the original 
// http://stackoverflow.com/a/14679003/4376737 
std::string find_and_replace(string str, const string& find, const string& replace) 
{ 
    size_t pos = 0; 
    while ((pos = str.find(find, pos)) != string::npos) { 
    str.replace(pos, find.length(), replace); 
    pos += replace.length(); 
    } 

    return std::move(str); 
} 
void change(list <char> &myList) 
{ 
    list<char> newlist; 

    std::stringstream ss; 
    for (auto&& it = myList.begin(); it != myList.end(); ++it) { 
    if (*it != ' ') { 
     ss << *it; 
    } else { 
     auto&& newstr = find_and_replace(ss.str(), "ph", "f"); 
     newstr = find_and_replace(newstr, "w", "v"); 
     for (auto&& ch : newstr) { 
     newlist.push_back(ch); 
     } 
     newlist.push_back(' '); 
     std::stringstream().swap(ss); //this clears the stringstream 
    } 
    } 

    myList = newlist; 
} 

Ausgang:

hamper moshpit phile wwwphwwwf 

hamper moshpit file vvvfvvvf