Replace funktioniert nicht
-
Hallo!
Sorry erstmal für den wenig aussagekräfitgen Titel, da ich mir jedoch den Grund für den Fehler kein Stück erklären kann, ist mir kein besserer eingefallen. Also erstmal der Code, auf dem mein ganzes Problem basiert:
#include <iostream> #include <fstream> #include <cstdlib> #include <stdexcept> #include <string> #include <vector> #include <algorithm> #include <ctype.h> using namespace std; string genrandfileout(char filename[255]) { string row; vector<string> content; ifstream file(filename); if (!file) { return "Die Installation von CINA ist beschädigt. Programm abgebrochen."; } while(getline(file,row)) content.push_back(row); int size = content.size(); int random = rand() % size + 1; cout << content[random-1]; return content[random-1]; } string UpToLow(string str) { int length = str.length(); for (int i=0;i<length;i++) { if (str[i] >= 0x41 && str[i] <= 0x5A) str[i] = str[i] + 0x20; } return str; } int main() { // Zufallszahlen - Seed Deklarieren // --START-- srand(time(0)); // --END-- // Lizenzabfrage - Erwartet Ja/Nein-Antwort // --START-- string license; cout << "Willkommen zu CINA (Computer based Intelligence Network Application)!\n"; cout << "Diese Software unterliegt der General Public License (GNU).\n"; cout << "Sie dürfen diese Software duplizieren, ändern und kommerziell nutzen,\n"; cout << "solange der Autor namentlich und im offiziellen Impressum genannt wird.\n"; cout << "Durch die Nutzung dieser Software erklären Sie sich mit diesen Beding-\n"; cout << "ungen einverstanden. Nichteinhaltung dieser Bedingungen wird Straf-\n"; cout << "rechtlich geahndet werden! Sind sie einverstanden? (j/n)\n>>> "; while(license != "j" && license != "n") { getline (cin, license); } // --END-- // Begrüßung (0001-0002) // --START-- char filename0001[255] = "file0001.txt"; genrandfileout(filename0001); char filename0002[255] = "file0002.txt"; genrandfileout(filename0002); cout << endl; // Namensabfrage (0003-0004) // --START-- string param0001[] = {"ich","heiße","mein","name","werde","genannt","man","nennt","mich","nenn","bin","nenne","!","."," " }; size_t found; string strusername; int till = 1; int set; char filename0003[255] = "file0003.txt"; char filename0004[255] = "file0004.txt"; char filename0005[255] = "file0005.txt"; char filename0006[255] = "file0006.txt"; genrandfileout(filename0003); cout << endl << ">>> "; getline (cin, strusername); strusername = UpToLow(strusername); while(till==1) { for(int i=0; i<15; i++) { found=strusername.find(param0001[i]); if (found!=string::npos) { till = 1; set = 1; strusername.replace(strusername.find(param0001[i]),param0001[i].length(),""); } else { if(set!=1) { till = 0; } } } set = 0; } if(strusername == "") { genrandfileout(filename0006); cout << endl; strusername = "Nutzer"; } else { genrandfileout(filename0004); cout << " " << strusername << "!" << endl; } genrandfileout(filename0005); // --END-- return 0; }Die wichtigen Abschnitte in diesem Code sind einmal die Funktion UpToLow und der Teil "Namensabfrage". Um in einer Eingabe die Wörter zu durchsuchen, EGAL, ob sie groß oder klein geschrieben sind, wird aktuell der Ausgangsstring komplett in Lower-Case umgewandelt (mit der Funktion UpToLow) und danach halt durchsucht. Dadurch ist es egal, ob der User "ich", "Ich" oder etwa "IcH" eingibt. Allerdings dient die Funktion ja dazu, dass hinterher im String lediglich noch der Benutzername übrig bleibt, der dann ja auch in Lower-Case umgewandelt wurde. Also aus "Ich heiße Mark" bleibt hinterher der kleingeschriebene Name "mark" übrig. Am liebsten wäre es mir daher, wenn ich den Originalstring nicht erst umwandeln müsste, um ihn zu durchsuchen. Da bin ich dann auf eine Idee gekommen:
Wenn ich den Originalstring (sagen wir "Ich heiße Mark") kopiere und die Kopie in lower-case umwandele, kann ich doch einfach die Kopie durchsuchen und, da die Wörter ja trotzdem in beiden Strings an der gleichen Stelle sind, im Originalstring durchsuchen. Der Teil im Code würde dann so aussehen:
// Namensabfrage (0003-0004) // --START-- string param0001[] = {"ich","heiße","mein","name","werde","genannt","man","nennt","mich","nenn","bin","nenne","!","."," " }; size_t found; string strusername; string temp; int till = 1; int set; char filename0003[255] = "file0003.txt"; char filename0004[255] = "file0004.txt"; char filename0005[255] = "file0005.txt"; char filename0006[255] = "file0006.txt"; genrandfileout(filename0003); cout << endl << ">>> "; getline (cin, strusername); temp = UpToLow(strusername); while(till==1) { for(int i=0; i<15; i++) { found=temp.find(param0001[i]); if (found!=string::npos) { till = 1; set = 1; strusername.replace(temp.find(param0001[i]),param0001[i].length(),""); } else { if(set!=1) { till = 0; } } } set = 0; } if(strusername == "") { genrandfileout(filename0006); cout << endl; strusername = "Nutzer"; } else { genrandfileout(filename0004); cout << " " << strusername << "!" << endl; } genrandfileout(filename0005); // --END--Bei dieser Veränderung bekomme ich jedoch folgenden Fehler angegeben:
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::replaceWeiß jemand, woran das liegt und was ich falsch mache? Danke schonmal im Voraus für eure Hilfe

-
Naja. Die Fehlermeldung sagt doch eigentlich alles.
Du befindest dich ausserhalb des Bereiches, auf den du zugreifen darfst.
Am besten schaust du mal, wo der Fehler auftritt (sollte kein Problem sein, da ja lediglich 2x replace aufgerufen wird), gehst dann da mal mit dem Debugger hin und schaust, was du falsch machst. Ob einfach die Grösse nicht stimmt, oder du wirklich ausserhalb deines Bereiches zugreifst.
-
Ich Blick da nich durch... Im Grunde versuche ich doch einfach nur eine Variable zu ändern! Da es ohne die zwei Variablen ja ohne Probleme funktioniert...
-
Mefisto schrieb:
Wenn ich den Originalstring (sagen wir "Ich heiße Mark") kopiere und die Kopie in lower-case umwandele, kann ich doch einfach die Kopie durchsuchen und, da die Wörter ja trotzdem in beiden Strings an der gleichen Stelle sind, im Originalstring durchsuchen.
Die Wörter sind aber nur bis zum ersten Ersetzungsvorgang an derselben Stelle.
-
DANKE

Wo ist meine Logik nur hin

Danke danke

endlich zwei Nächte verzweifelten bastelns gelöst

-
Schau mal hier nach, ob du alles richtig verstanden hast, was replace macht:
http://www.cplusplus.com/reference/string/string/replace.html
-
Jojo, jetzt gehts ja auch
War nur einfach ein simpler Denkfehler... Ich editiere jetzt den temp-String auch mit, dann klappts...Nur noch eine Frage: Wie kann ich die Anzahl der Elemente eines Arrays auslesen?
-
Mefisto schrieb:
Nur noch eine Frage: Wie kann ich die Anzahl der Elemente eines Arrays auslesen?
Gar nicht.
Benutz dazu lieber einen std::vector, oder andernfalls musst du dir irgendwo merken, wie viele Elemente das Array enthält.
-
Mefisto schrieb:
Nur noch eine Frage: Wie kann ich die Anzahl der Elemente eines Arrays auslesen?
sizeof( array ) / sizeof( array[0] )
Das geht aber wirklich nur bei Arrays, nicht bei Zeigern.