Problem mit string
-
Hallo
ich will ein Programm schreiben das alle Zeilen einer Datei nacheinander einliest und überprüft ob eine bestimmte Zeichenkette darin vorhanden ist! Das sieht bei mir folgendermasen aus:#include <iostream> #include <fstream> #include <string> using namespace std; int main() { ifstream dict("ger-eng.ding", ios::in); if(!dict.good()){ cout <<"ger-eng.ding konnte nicht gefunden werden\n"; sleep(5); return 1; } char voc[20]; cin >> voc; char *pvoc = &voc[0]; char next_line[500]; int opp =1; do { dict.getline(next_line, 499); string *translation = new string(next_line); if(translation->find(pvoc)!=-1){ //pvoc gefunden cout << "\n\n"<< opp++ <<". Möglichkeit" << endl; cout << translation << endl; } }while(!dict.eof()); return 0; }Jetzt weiß ich jedoch nicht was da nicht stimmt! Es wird immer nur die Zeile angezeigt in der das Wort zum ersten Mal auftaucht! An was liegt das bitte?
-
std::string::find sucht halt eben nur bis zur ersten Übereinstimmung.
-
Ich habe mal ein paar Dinge kommentiert:
#include <iostream> #include <fstream> #include <string> using namespace std; int main() { ifstream dict("ger-eng.ding", ios::in); if(!dict.good()){ //if(dict) ist besser... cout <<"ger-eng.ding konnte nicht gefunden werden\n"; sleep(5); //wo kommt das her? return 1; } char voc[20]; //wieso kein std::string? cin >> voc; char *pvoc = &voc[0]; //wozu? char next_line[500]; //wieso kein std::string? int opp =1; do { dict.getline(next_line, 499); //std::getline wäre besser als std::istream::getline string *translation = new string(next_line); //wieso mit new? java-programmierer? if(translation->find(pvoc)!=-1){ //besser std::string::npos und nicht -1 //pvoc gefunden cout << "\n\n"<< opp++ <<". Möglichkeit" << endl; cout << translation << endl; } //wenn schon mit new, dann das delete nicht vergessen... }while(!dict.eof()); //kann fehlschlagen, weil eof u.U. erst gesetzt wird, wenn man versucht hinter dem Ende zu lesen return 0; }
-
Kóyaánasqatsi schrieb:
std::string::find sucht halt eben nur bis zur ersten Übereinstimmung.
Schon richtig, nur wird ja über dict.getline(next_line, 499); immer eine neue Zeile geholt.
Btw finde ich das mixen von std::string und char* auch nicht so toll, entweder du bleibst bei den alten C-Strings, und benutzt z.B. strstr() als Vergleichsmethode, oder du schreibst gleich alles mit std::string.
#include <iostream> #include <fstream> #include <string> using namespace std; int main() { ifstream dict("ger-eng.ding", ios::in); if(!dict.is_open()) { cout <<"ger-eng.ding konnte nicht gefunden werden\n"; return 1; } char voc[20]; cin >> voc; char next_line[500]; int opp = 1; while( !dict.eof() ) { dict.getline(next_line, 499); if( strstr( next_line, voc ) != 0 ) { //pvoc gefunden cout << "\n\n"<< opp <<". Möglichkeit" << endl; cout << next_line << endl; opp++; } } return 0; }Das währe die (effizientere) Methode über die guten alten C-Strings.
Also wenn deine eingehende Datei keine Fehler hat erscheint mir der Code eigentlich richtig.
-
beamer schrieb:
Jetzt weiß ich jedoch nicht was da nicht stimmt! Es wird immer nur die Zeile angezeigt in der das Wort zum ersten Mal auftaucht! An was liegt das bitte?
Bei mir wird jeweils die Adresse des Aktuellen Stringobjekts angezeigt.
Lars
-
Ich hab mal reingeschrieben was ich mir dabei gedacht habe...
#include <iostream> #include <fstream> #include <string> using namespace std; int main() { ifstream dict("ger-eng.ding", ios::in); if(dict){ cout <<"ger-eng.ding konnte nicht gefunden werden\n"; sleep(5); //wo kommt das her? -> Hab Fedora return 1; } char voc[20]; //wieso kein std::string? -> brauch dann sowieso nen char-Pointer cin >> voc; char *pvoc = &voc[0]; //wozu? -> Brauche char-Pointer auf Zeichenkette für find() char next_line[500]; //wieso kein std::string? ->getline braucht doch auch nen char-Pointer int opp =1; do { dict.getline(next_line, 499); //std::getline wäre besser als std::istream::getline string translation(next_line); if(translation->find(pvoc)!=string::npos){ //pvoc gefunden cout << "\n\n"<< opp++ <<". Möglichkeit" << endl; cout << translation << endl; } }while(!dict.eof()); //kann fehlschlagen, weil eof u.U. erst gesetzt wird, wenn man versucht hinter dem Ende zu lesen -> was kann man sonst nehmen? return 0; }
-
sorry so natürlich
if(translation.find(pvoc)!=string::npos){ //pvoc gefunden cout << "\n\n"<< opp++ <<". Möglichkeit" << endl; cout << translation << endl; }
-
Wie gesagt, wenn du schon mit C-Strings hantierst dann benutz die auch konsequent und kopier nicht den C-String in nen std::string nur damit du einen Vergleich ausführen kannst. Das ist total unnötig.
char *pvoc = &voc[0]; //wozu? -> Brauche char-Pointer auf Zeichenkette für find()
Das ist auch blödsinn, schließlich ist voc ja nur ein Zeiger auf das erste Element deiner Zeichenkette. char *pvoc = voc; hätte den selben Effekt, und dann kannst du auch gleich voc weiterbenutzen.
-
beamer schrieb:
sorry so natürlich
wen man jetzt noch
if(!dict)schreibt, funktioniert das Programm. Wo ist das Problem?
Lars
-
Bischen entschlackt und ohne Speicherleck...
int main() { std::ifstream dict("ger-eng.ding"); //ist eh ein *i*fstream, also kein ios::in noetig if(dict) //wenn stream okay... { std::string voc; std::getline(std::cin, voc); //in std::string einlesen. Laenge der Eingabe egal std::string line; std::size_t opp = 1; while(std::getline(dict, line)) //solange zeilen da-> einlesen { if(line.find(voc) != std::string::npos) //kein char* noetig { std::cout << "\n\n"<< opp <<". Möglichkeit\n" << line << '\n'; ++opp; } } } else //stream ist nicht okay { std::cout <<"ger-eng.ding konnte nicht gefunden werden\n"; } }
-
Ok danke jetzt funktionierts!