getline - String wird falsch übergeben
-
27 int Parser::parsen(string Dateiname) 28 { 29 30 ifstream f; 31 ofstream index; //ifstream = Lesen, ofstream = Schreiben, fstream = flexibel 32 f.open(Dateiname.c_str()); //bei fstream zusätzlicher Parameter nötig 33 index.open("index"); 34 if(f.is_open()) //testet ob Datei wirklich geöffnet ist 35 { 36 char c; 37 char zeichendavor = ' '; 38 39 /* Problematik: 40 * - Problem bei fehlenden Leerzeichen */ 41 42 while(!f.eof()) //testet ob Datei zuende ist 43 { 44 f.get(c); 45 46 47 switch(c) 48 { 49 case ' ': case '\n': 50 switch(zeichendavor) 51 { 52 case ' ': case '\n': break; 53 default: 54 index << "\t\t" << Dateiname << "\n"; 55 break; 56 } 57 break; 58 case ',': case '!': case '?': case '.': case '"': break; 59 default: 60 switch(zeichendavor) 61 { 62 case ',': case '!': case '?': case '.': case '"': 63 index << "\t\t" << Dateiname << "\n" << c; break; 64 default: index << c; 65 break; 66 } 67 break; 68 } 69 zeichendavor = c; 70 71 } 72 73 } 74 f.close(); 75 index.close(); 76 return 0; 77 } 78Also, das ist parsen(string Dateiname)
Wenn ich den Dateiname direkt einfüge, also z.b.: parsen(test.txt) funktioniert alles tadellos (abgesehen von etlichen Ausnahmefällen die ich noch nicht drinne habe, aber das stört erstmal nicht) und in der index steht dann z.B.
Ich test.txt
weiß test.txt
nicht test.txt
mehr test.txt
weiter test.txtWenn ich genau das allerdings mithilfe de getline-Funktion probiere und die Dateinamen aus einer Liste ziehe, ist die index vollkommen leer. Warum?
-
Debugge doch einfach und schau mal, was in 'Dateiname' genau steht und ob er dann die Datei auch öffnen kann...
Ich empfehle aber auch std::string mit der zugehörigen freien Funktion 'getline(string, istream)' zu benutzen.
Außerdem kannst du das Öffnen der Datei gleich beim Konstruktor vornehmen:
ifstream f(Dateiname.c_str());
-
Also, die genannten Dinge habe ich geändert, das Problem bleibt aber leider dasselbe.
Ich habe bereits versucht zu Debuggen und er kommt auch in parsen(string Dateiname) herein, aber dennoch wird nichts daraus. Habe ddd (GUI für gdb unter Ubuntu) benutzt, werde allerdings aus den Werten für die Variablen nicht schlau. Auf jeden Fall scheint er alles in der parsen-Funktion auszuführen.Ich gehe ja auch richtig in der Annahme, dass er in der Index nur anhängt und diese nicht jedes Mal neu erstellt oder gegebenenfalls irgendetwas löscht, oder?
Mache ich in die parsen eine Ausgabe für den Dateinamen rein, so gibt er diesen auch korrekt aus.
Danke auf jeden Fall schoneinmal für die Tipps.
EDIT: Ich habe gerade einmal einen else-Zweig reingemacht, um zu schauen, ob er die Dateien öffnet, ... und siehe da, er tut es nicht.
Woran könnte das liegen?
-
Mach aus:
int Parser::parsen(string Dateiname)doch einfach mal:
int Parser::parsen(const char *Dateiname)Ich weiß nämlich nicht ob es da Datenverluste/-veränderungen geben kann. Einfach mal ausprobieren und debuggen...
-
Ich habe jetzt die andere getline Funktion genommen, so dass ich prinzipiell einen String ausgegeben bekomme und keinen char-array mehr, ... ohne es jetzt ausprobiert zu haben, ... wird das nicht auf eine Fehlermeldung hinauslaufen, wenn ich nun sage, der Parameter sei ein char*? Weshalb in diesem Fall eigentlich das "const"?
EDIT: Ich habe es nun vollständig mit const char* probiert, doch bleibt das Problem dasselbe: Er kann die Dateien nicht öffnen, obwohl er den richtigen Dateinamen überliefert bekommt und die Dateinamen innerhalb der parsen-Funktion auch korrekt ausgeben kann.
-
Ich habe jetzt die andere getline Funktion genommen, so dass ich prinzipiell einen String ausgegeben bekomme und keinen char-array mehr, ... ohne es jetzt ausprobiert zu haben, ... wird das nicht auf eine Fehlermeldung hinauslaufen, wenn ich nun sage, der Parameter sei ein char*? Weshalb in diesem Fall eigentlich das "const"?
EDIT: Ich habe es nun vollständig mit const char* probiert, doch bleibt das Problem dasselbe: Er kann die Dateien nicht öffnen, obwohl er den richtigen Dateinamen überliefert bekommt und die Dateinamen innerhalb der parsen-Funktion auch korrekt ausgeben kann.
EDIT2: Ich seh gerade, dass er ungewöhnlicherweise, trotz 2er Dateien, nur einmal "Kann Datei nicht öffnen!" ausgibt.
Nocheinmal der vollständige Code, wie er jetzt ist:
#include "Parser.h" Parser::Parser(string Liste) { //parsen("test.txt"); //funktioniert ifstream l(Liste.c_str()); if(l.is_open()) { string a; while(!l.eof()) { getline(l, a); //delim = \n parsen(a); //funktioniert nicht cout << a << " "; } l.close(); } else { cout << "Datei nicht lesbar!!" << endl; } } int Parser::parsen(string Dateiname) { ifstream f(Dateiname.c_str()); ofstream index; //ifstream = Lesen, ofstream = Schreiben, fstream = flexibel index.open("index"); if(f.is_open()) //testet ob Datei wirklich geöffnet ist { char c; char zeichendavor = ' '; /* Problematik: * - Problem bei fehlenden Leerzeichen */ while(!f.eof()) //testet ob Datei zuende ist { f.get(c); switch(c) { case ' ': case '\n': switch(zeichendavor) { case ' ': case '\n': break; default: index << "\t\t" << Dateiname << "\n"; break; } break; case ',': case '!': case '?': case '.': case '"': break; default: switch(zeichendavor) { case ',': case '!': case '?': case '.': case '"': index << "\t\t" << Dateiname << "\n" << c; break; default: index << c; break; } break; } zeichendavor = c; } f.close(); index.close(); } else cout << "Kann Datei nicht öffnen!" << endl; return 0; }
-
Aus
l.open(Liste.c_str());mal
l.open(Liste.c_str(), std::ios::in);machen...
-
Keine Änderung.
Ausgabe:
test.txt test2.txt Kann Datei nicht öffnen!Ändere ich den else-Zweig auf:
else cout << "Kann " << Dateiname << " nicht öffnen!" << endl;Bekomme ich:
test.txt test2.txt Kann nicht öffnen!Er kennt also den Dateinamen nicht mehr. Hat das einen Grund?
Setze ich jedoch eine Ausgabe des Dateinames an die erste Stelle in parsen, so kann er es noch.
-
Dann check mal den Pfad. Haste text1.txt auch im richtigen Projekteordner?
-
Ja, befindet sich alles in einem Ordner.
Und wie gesagt, wenn ich parsen("test.txt"), bzw. parsen("test2.txt") aufufe und ausführe, macht er auch alles, wie er es soll, kann die Datei lesen und in der Index steht das gewünschte.
-
Kóyaánasqatsi schrieb:
Mach aus:
int Parser::parsen(string Dateiname)doch einfach mal:
int Parser::parsen(const char *Dateiname)Ich weiß nämlich nicht ob es da Datenverluste/-veränderungen geben kann. Einfach mal ausprobieren und debuggen...
Kóyaánasqatsi schrieb:
Aus
l.open(Liste.c_str());mal
l.open(Liste.c_str(), std::ios::in);machen...
Hauptsache wild im Zeug rumraten...
Der erste Vorschlag ist nicht wirklich ratsam, wenn die.ina mitstd::getline()flexibel sein will. Wie kommst du eigentlich darauf, dass man durch denstd::stringDaten verlieren könnte? Allerdings könnte sich eine Const-Referenz, alsoconst std::string& Dateinameaus Performancegründen empfehlen.Dein zweiter Vorschlag bringt überhaupt nichts.
die.ina schrieb:
index.open("index");Bist du sicher, dass die Datei "index" heisst (ohne Endung)?
Was willst du eigentlich genau erreichen? In einer Datei die Namen anderer Dateien lesen, die du dann einzeln parst? Übrigens rate ich dir, so schnell wie möglich den Umgang mit dem Debugger zu lernen. Das ist eines der hilfreichsten und mächtigsten Werkzeuge eines Programmierers.
-
Also, vll ist es etwas umständlich, aber ich weiß nicht, wie ich es besser machen soll.
1. Schritt: 1000e von Textdateien als Liste in einer Datei speichern.
2. Schritt: Die einzelnen Wörter aus den Textdateien in einer weiteren Datei speichern, inklusive dem Namen der Textdatei in welcher sie gefunden wurden.
3. Schritt: Diese Textdatei dann sortieren und bei gleichen Wörtern die Dateinamen als Liste hinter dem jeweiligen Wort speichern.
4. Schritt: Nach Wörtern suchen und eben anzeigen, wo sie zu finden sind.
...Momentan hänge ich zwischen Schritt 1 und 2, wobei 1 eigentlich noch vollkommen fehlt.
Index ohne Endung ist kein Problem, ... Linux.
-
Hmm. Oben hast du aber gesagt, dass es ja funktioniert..
Also klappt das browsen durch die Ordner nicht? Respektive hast du Probleme mit Pfaden?