Aus .txt Datei lesen
-
hmm hab nur seine Funktionen verbessert bzw. korrigiert.
-
Hab schon soviele Bücher aber die bringen alle nix, oder ich bin in irgend nem kapitel hängen geblieben...weil wirklich langweilig wurde, eigentlich hab ich mir jetzt vorgenommen, noch die ganzen String Funktionen zu lernen...weil ich mich da noch nicht auskenne, also z.B. wie man alles in Großbuchstaben umwandelt....
Und danach wollte ich eigentlich das Buch "Die C++ Standardbibliothek" durchmachen, das hab ich mir vor einiger Zeit gekauft und es liegt halt in meinem Regal rum...ich hoff wenn ich mit dem fertig bin hab ich bisschen mehr Wissen.
Und das mit den Datein mach ich eigentlich gerade nur um mal n kleines bisschen "action" reinzubringen, weil ich mach das jetzt echt schon lange (6 Moante sind untertrieben) komm aber irgendwie nicht auf nen grünen Zweig....weil ich wills zwar können aber irgendwie stell ich mich so an oder ich weiß nicht....und mir fällt eigentlch auch gerade gar nicht mehr ein was ich programmieren soll, weil alles ist so bock langweilig wenn man immer wieder das gleiche in der blöden schwarzen Konsole macht. Aber so "macht's mich schon an" wenn ich hier andere Beiträge lese...und dann denk ich mir wieder Augen zu und durch irgendwann wirst auchs du blicken --> auch ein blindes Huhn findet mal ein Korn.
So jetzt hab ich mal hier rumgelabbert und mein Herz ausgeschüttet ich mach trotzdem weiter mit der Sprache!!!
Ich mein so schwierig kann C++ doch gar nicht sein? Ihr könnt es doch auch alle? Mh?
Vll. liegts bei mir auch daran das ich mir von anfang an das falsche Lehrbuch gekauft habe --> Jetzt lerne ich C++?
Mh ach ich weiß auch nicht, und so schnell gebe ich noch nicht auf und ihr müsst euch weiter mit meinen komischen Fragen rumärgern.
MfG
Stromberg
-
Stromberg schrieb:
Hab schon soviele Bücher aber die bringen alle nix, oder ich bin in irgend nem kapitel hängen geblieben...weil wirklich langweilig wurde, eigentlich hab ich mir jetzt vorgenommen, noch die ganzen String Funktionen zu lernen...weil ich mich da noch nicht auskenne, also z.B. wie man alles in Großbuchstaben umwandelt....
Und danach wollte ich eigentlich das Buch "Die C++ Standardbibliothek" durchmachen, das hab ich mir vor einiger Zeit gekauft und es liegt halt in meinem Regal rum...ich hoff wenn ich mit dem fertig bin hab ich bisschen mehr Wissen.
Und das mit den Datein mach ich eigentlich gerade nur um mal n kleines bisschen "action" reinzubringen, weil ich mach das jetzt echt schon lange (6 Moante sind untertrieben) komm aber irgendwie nicht auf nen grünen Zweig....weil ich wills zwar können aber irgendwie stell ich mich so an oder ich weiß nicht....und mir fällt eigentlch auch gerade gar nicht mehr ein was ich programmieren soll, weil alles ist so bock langweilig wenn man immer wieder das gleiche in der blöden schwarzen Konsole macht. Aber so "macht's mich schon an" wenn ich hier andere Beiträge lese...und dann denk ich mir wieder Augen zu und durch irgendwann wirst auchs du blicken --> auch ein blindes Huhn findet mal ein Korn.
So jetzt hab ich mal hier rumgelabbert und mein Herz ausgeschüttet ich mach trotzdem weiter mit der Sprache!!!
Ich mein so schwierig kann C++ doch gar nicht sein? Ihr könnt es doch auch alle? Mh?
Vll. liegts bei mir auch daran das ich mir von anfang an das falsche Lehrbuch gekauft habe --> Jetzt lerne ich C++?
Mh ach ich weiß auch nicht, und so schnell gebe ich noch nicht auf und ihr müsst euch weiter mit meinen komischen Fragen rumärgern.
MfG
StrombergHmmm, hört sich schon frustrierend an. Schon deine erste Frage hier, deutete darauf hin, das du irgendwas falsch lernst.
In jedem vernüftigen Tutorial, würdest du direkt lernen das ein getline(file,string) reichen würde um deinen "Hans Werner Olm" zu bekommen.
Oder einfach dreimal, genau wie bei cin, >> benutzen:
//umständlich, soll aber nur verdeutlichen string a,b,c,name; file >> a,b,c; name = a + " " + b + " " + c; /* Wenn du willst das jmd dir über die Konsole "Hans Werner Olm" eingeben soll, dann würdest du es ja auch so machen: file >> a,b,c; Du musst cin und die ifstream gleich sehen, nur die Quelle von der die Daten bezogen werden ist unterschiedlich. Einmal Tastatur, einmal Datei ... */Wesentlich einfach natürlich das:
string name = ""; getline(file,name);Das alles hat dir ja Maxi schon am Anfang vorgeschlagen.
So einfach kann das sein

Wenn du jetzt eine ganze Datei einlesen willst, denkst du weiter:
//Mit getline lese ich mir ja eine Zeile aus //Also muss ich jetzt, solange getline Machen bis es keine Zeilen mehr gibt ifstream file("datei.txt"); if(!file) // return oder sonstwas //oder if(file) schreiben und in { } mit der Datei arbeiten /* if(file) { arbeiten mit datei } */ // Nun Zeilen auslesen, bis zum EOF string fileText = ""; // Alles immer schön initalisieren while(!file.eof()) { string temp = ""; getline(file,temp); fileText += temp + "\n"; } // gesamter Dateiinhalt nun in fileText;Nun spielen wir ja hier mit C++ und das alles ist noch nicht ganz so sicher.
Das Problem ist das file.eof() gibt dir nur EOF zurück, wenn es mal eingelesen wurde. Das heißt eof() weiß nicht das gleich EOF kommen könnte.
Demnach könnte unerwartetes passieren und wir EOF einlesen:while(!file.eof()) { string temp = ""; getline(file,temp); // falls wir EOF einlesen sollten, dann raus aus schleife if(file.eof()) break; fileText += temp + "\n"; }Nun ist gut, aber es geht noch schöner:
string temp = ""; while(getline(file,temp)) { fileText += temp + "\n"; } // getline liefert den stream wieder zurück // also sieht das nach getline so aus: while(file) // Dh wenn file ok ist läuft die Schleife und das ist es wenn zB nicht sowas wie EOF kommtNatürlich gibt es noch Sachen wie copy und iteratoren die alles auf eine Zeile bringen:
http://c-plusplus.net/forum/viewtopic-var-p-is-1280471.html#1280471
Aber lass das erst mal und arbeite normal um alles zu verstehen.Zu der Geschichte EOF gibts hier was schönes:
http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&faq=eof#Answ
Zudem noch jede Menge anderer nützlicher Tipps.So "Der Anschlag" läuft, muss los

-
Also vielen Danke erst mal an dich KasF für deine lange Erklärung.
Ich hab mich jetzt nochmal genau hingesetzt, und das von (D)Evil und von dir aufmerksam durchgelesn, bisschen rumprobiert, wieder euren Code angeschaut.... und ich bilde mir ein es nun verstanden zu haben. Das hier wäre mein Code:#include <iostream> #include <fstream> #include <string> using namespace std; int file_volume(ifstream &stream); bool file_input(string &file,const string input) ; int main() { string buffer; file_input(buffer,"D:\\Hans.txt"); cout << buffer << endl; return 0; } int file_volume(ifstream &stream) { int temp; if(stream) { stream.seekg(ios::beg,ios::end); temp=stream.tellg(); stream.seekg(ios::beg); } else { return 0; } } bool file_input(string &file,const string input) { ifstream data(input.c_str()); string temp; while(getline(data,temp)) { file=file+temp+"\n"; } if(file.length()!=file_volume(data)) { data.close(); return 0; } data.close(); return 1; }Jetzt is es aber doch ganz in Ordnung, is ja so ähnlich wie euer Code?
Das mit dem "while(getline(data,temp))...." was du mir erklärt hast KasF, ist natürlich schon n kleiner unterschied zu dem was ich gemacht habe
Dankeschön schon mal im Voraus.
-
hmm ...
stream.seekg(ios::beg,ios::end);... was soll das sein? Guck dir mal die genaue Deklaration von seekg an ... http://www.cppreference.com/cppio/seekg.html
int file_volume(ifstream &stream) // warum int? kann doch nur positiv lang sein ;) => std::size_t (meist das selbe wie unsigned int) { int temp; // warum hier schon anlegen? Wird doch nur genutzt wenn stream geöffnet ist ... if(stream) { stream.seekg(ios::beg,ios::end); // s. o. temp=stream.tellg(); // hmm tellg sollte aber std::streampos und nicht int zurückgeben. stream.seekg(ios::beg); // Und wenn du vorher nicht am Anfang der Datei warst? } else { return 0; } }...
bool file_input(string &file,const string input) { ifstream data(input.c_str()); // und was ist wenn du die Datei nicht öffnen konntest? (!data) // Was ist wenn in file schon was drin steht? string temp; while(getline(data,temp)) { file=file+temp+"\n"; } if(file.length()!=file_volume(data)) // wofür?! { data.close(); // unnötig ... return 0; } data.close(); // unnötig ... return 1; }
-
Zudem von (D)Evil noch. file_volume vergisst einmal was zurückzugeben

-
Joa, so gut isses anscheinend noch nicht, aber es ist besser als mein anfang.
Zu dem hier noch:if(file.length()!=file_volume(data)) // wofür?! { data.close(); // unnötig ... return 0; } data.close(); // unnötig ... return 1;Ich will doch 0 zurückgeben wenn es fehlgeschlagen hat und 1 zurückgeben wenn es funktioniert hat? Aber vll. ist das von mir n bissel komisch umgesetzt worden?
Was ist wenn in file schon was drin steht?
Das ist doch egal oder? Dann wird das halt einfach überschrieben und es steht halt was neus drin?
Dakeschön schon mal im Voraus.
-
#include <iostream> #include <fstream> #include <string> using namespace std; //int file_volume(ifstream &stream); bool file_input(string &file,const string input) ; int main() { string buffer; file_input(buffer,"D:\\Hans.txt"); cout << buffer << endl; return 0; } /*size_t file_volume(ifstream &stream) { if(stream) { int temp; stream.seekg(ios::beg,ios::end); temp=stream.tellg(); stream.seekg(ios::beg); } else { return -1; } }*/ bool file_input(string &file,const string input) { ifstream data(input.c_str()); if(data.is_open()) { string temp; while(getline(data,temp)) { file=file+temp+"\n"; } data.close(); return 1; } return 0; }Wie is es so? Habs nochmal überdacht!
eigentlich brauch ich jetzt die "file_volume" Funktion doch nicht mehr oder? Äh und was passt an meiner "file_volume" den nicht, die funktiuoniert doch prima? Wie funktioniert das den sonst mit dem "seekg"? Ich kann mit dem Link irgendwie nicht viel anfangen, da stand nicht grad viel drin...?
Dankeschön schon mal im Voraus.
-
Stromberg schrieb:
bool file_input(string &file,const string input) { // … return 1; } return 0; }Was soll eigentlich der Unsinn, '0' und '1' statt 'false' und 'true' zu benutzen?
Und außerdem halte ich die Lösung mit 'getline' für absoluten Overkill, wenn es doch viel einfacher über einen Stream geht. Wir wollen schließlich keine Zeilen einlesen sondern die gesamte Datei. Wie ich bereits gepostet habe, geht das mit *einer Zeile*!
-
Ah du hast da ja was gepostet, hab ich gar nicht gelesen:
string read_file(string const& fname) { return dynamic_cast<stringstream*>(&(stringstream() << ifstream(fname.c_str()).rdbuf()))->str(); }Ah mit einer Zeile ist das ja noch einfacher....bloß muss ich mir das erst noch ma genau anschauen, weil auf die schnell blick ich das jetzt nicht, und was ist den bite ein "dynamic_cast"?
Und zu dem TRUE und FALSE noch, also ich hab irgendwo auf so einer Internetseite mal gelesen das es gar nicht gut sein soll "TRUE" und "FALSE" zu verwenden, des hat da irgendjemand gesagt..(vll. find ichs wieder).
Aber eigentlich benutze ich auch immer TRUE und FALSE...weiß eiegtnlich auch nicht warum ich jetzt 1 und 0 genommen habe.
Und was meinst du mit Overkill? Meinst damit das es zu lange dauert?
Dankeschön schon mal im Voraus.
-
Konrad Rudolph schrieb:
string read_file(string const& fname) { return dynamic_cast<stringstream*>(&(stringstream() << ifstream(fname.c_str()).rdbuf()))->str(); }da ostream keine virtuelle basisklasse von stringstream ist, kannst du dir den dynamic_cast sogar sparen.
-
Konrad Rudolph schrieb:
Was soll eigentlich der Unsinn, '0' und '1' statt 'false' und 'true' zu benutzen?
Was soll daran Unsinn sein ???
Konrad Rudolph schrieb:
string read_file(string const& fname) { return dynamic_cast<stringstream*>(&(stringstream() << ifstream(fname.c_str()).rdbuf()))->str(); }Wenn du deine eine Zeile haben willst, dann lieber sowas:
string fileText = string(istreambuf_iterator<char>(file),istreambuf_iterator<char>());
-
queer_boy schrieb:
Konrad Rudolph schrieb:
string read_file(string const& fname) { return dynamic_cast<stringstream*>(&(stringstream() << ifstream(fname.c_str()).rdbuf()))->str(); }da ostream keine virtuelle basisklasse von stringstream ist, kannst du dir den dynamic_cast sogar sparen.
Ne, kann ich nicht, denn 'operator<<' gibt mir nunmal keinen stringstream zurück sondern einen 'basic_ostream<…>'. Aber ein 'static_cast' reicht natürlich.
Stromberg schrieb:
Und zu dem TRUE und FALSE noch, also ich hab irgendwo auf so einer Internetseite mal gelesen das es gar nicht gut sein soll "TRUE" und "FALSE" zu verwenden, des hat da irgendjemand gesagt..(vll. find ichs wieder).
Stimmt auch, ich sprach aber von 'true' und 'false', nicht von 'TRUE' und 'FALSE'. 'true' und 'false' sind Bool-Konstanten, 1 und 0 hingegen sind Int-Konstante.
Und was meinst du mit Overkill? Meinst damit das es zu lange dauert?
Ich nehme an, dass es länger dauert aber das meinte ich nicht. Ich meinte, dass der Code einfach eine falsche Semantik vermittelt. Er suggeriert, dass hier Zeilen eingelesen werden. Overkill ist es deswegen, weil hier mehr Operationen stattfinden als nötig sind und das führt natürlich potentielle Fehlerquellen ein. Es widerspricht einfach dem Grundsatz, alles so einfach wie möglich zu halten.
Zu 'dynamic_cast': Hier wird zur Laufzeit geprüft, ob der Cast vollzogen werden kann. Sollte das nicht der Fall sein, wird 0 zurückgegeben.
-
Konrad Rudolph schrieb:
wird 0 zurückgegeben.
Und die 0 landet dann im string und es macht *boom*

Konrad Rudolph schrieb:
Ich nehme an, dass es länger dauert aber das meinte ich nicht. Ich meinte, dass der Code einfach eine falsche Semantik vermittelt. Er suggeriert, dass hier Zeilen eingelesen werden. Overkill ist es deswegen, weil hier mehr Operationen stattfinden als nötig sind und das führt natürlich potentielle Fehlerquellen ein. Es widerspricht einfach dem Grundsatz, alles so einfach wie möglich zu halten.
Hättest es ja auch vorher so schreiben können

-
KasF schrieb:
Konrad Rudolph schrieb:
Was soll eigentlich der Unsinn, '0' und '1' statt 'false' und 'true' zu benutzen?
Was soll daran Unsinn sein ???
Es vermittelt eine falsche Semantik. Wozu gibt's denn verschiedene Typen? Wenn man die nicht benutzt, muss man auch nicht C++ programmieren, dann reicht eine Sprache ohne Typen.
string fileText = string(istreambuf_iterator<char>(file),istreambuf_iterator<char>());Hm. Irgendwie hatte ich in Erinnerung, dass man hier erst ein Flag setzen müsste, damit Leerzeichen nicht überlesen werden.
Aber meine Methode ist schneller :p
-
Konrad Rudolph schrieb:
Es vermittelt eine falsche Semantik.
Das reicht mir schon als Argument. Überzeugt.
Konrad Rudolph schrieb:
Hm. Irgendwie hatte ich in Erinnerung, dass man hier erst ein Flag setzen müsste, damit Leerzeichen nicht überlesen werden.
Das macht das schöne buf am Ende von ifstreambuf

Konrad Rudolph schrieb:
Aber meine Methode ist schneller :p
Wohlmöglich ...
-
Konrad Rudolph schrieb:
queer_boy schrieb:
Konrad Rudolph schrieb:
string read_file(string const& fname) { return dynamic_cast<stringstream*>(&(stringstream() << ifstream(fname.c_str()).rdbuf()))->str(); }da ostream keine virtuelle basisklasse von stringstream ist, kannst du dir den dynamic_cast sogar sparen.
Ne, kann ich nicht, denn 'operator<<' gibt mir nunmal keinen stringstream zurück sondern einen 'basic_ostream<…>'. Aber ein 'static_cast' reicht natürlich.
war das nicht klar?
nur falls es dich interessiert, nicolai josuttis ist deiner meinung, was die geschwindigkeit der lösungen anbelangt
außer der string-konstruktor schafft es, extrem gut mit iteratoren (streambuf iteratoren) umzugehen.
-
queer_boy schrieb:
Konrad Rudolph schrieb:
Aber ein 'static_cast' reicht natürlich.
war das nicht klar?
Nein, aber Du hast recht: Es hätte mir klar sein können. *deng*
nicolai josuttis ist deiner meinung, was die geschwindigkeit der lösungen anbelangt

Das freut mich – wobei es mich ehrlich gesagt aber wundert (ich hab's erst nach Performance-Tests geglaubt). Der string-Konstruktor müsste doch in der Lage sein, genauso wie der stringstream einen dynamisch wachsenden Buffer zu verwenden und die Daten blockweise einzulesen. Oder übersehe ich da irgendwas?
-
string könnte in der tat schneller sein, wenn es die segmented sequence optimization verwenden würde*. das problem ist, dass die iteratoren intern ständig checken, wieviel noch im buffer ist (direkt oder indirekt via sbumpc) und ohne eine blockorientierte spezialisierung ist das schwer wegzuoptimieren. das problem hast du mit dem stringstream und dem buffer nicht, weil der sich das ganze tatsächlich geblockt einliest. (übrigens tritt dasselbe problem auf mit deque, weil deque auch blockorientiert arbeitet)
*(die implementierung von gcc 4.1.2 ist sogar tatsächlich schneller, wenn die datei eine bestimmte größe unterschreitet, weil sie intern einen fixen buffer verwendet)
-
queer_boy schrieb:
(übrigens tritt dasselbe problem auf mit deque, weil deque auch blockorientiert arbeitet)
Das finde ich interessant: Warum sollte die Deque mit Segmenten arbeiten? Ich kenne nur die naiven Implementierungen einer Deque als doppelt verkettete Liste oder als Ringpuffer. Wie funktioniert das mit Segmenten? Ich habe über Google auf die Schnelle keine Informationen finden können.