Zeilenposition bei dateilesen
-
Also verstehe ich richtig ich merke mir einen integer wert um nachher mit diesem integer wert die position in dieser Datei anzuspringen. Das geht ???
-
ismaild schrieb:
Also verstehe ich richtig ich merke mir einen integer wert um nachher mit diesem integer wert die position in dieser Datei anzuspringen. Das geht ???
Nein - das habe ich auch nicht gesagt. Du kannst mit dem LineCounter (hinter dem Link) die Zeilennummer feststellen. Das war eine Antwort auf Deine Frage am Anfang. Mit der Zeilennummer kannst Du dann im Editor Deiner Wahl an die Zeile in der Datei springen; z.B. um zu sehen, warum genau da ein Lesefehler aufgetreten ist.
Wenn Du innerhalb eines Einlesevorgangs in C++ an eine bestimmte Stelle der Datei hinspringen willst, so nützt die Zeile rein gar nichts. Vielmehr kann man sich mit pos=tellg() die aktuelle Position merken und später mit seekg(pos) wieder hinspringen.
-
Besten dank werner_loggoff,
genau darauf wollte ich eigentlich hinaus, ich möchte mir die Position merken und nachher wieder dort hin springen. Kein Texteditor, alles programmatisch und soweit ich das gelesen habe gibt mit tellg() die Position nur Zeichenweise wieder oder setzt sie mit seekg() Zeichenweise. Da meistens jede Zeile unterschiedlich ist( von der Zeichenanzahl versteht sich) dürfte sich das jetzt glaube ich erledigt haben oder gibt es eine funktion die auch zeilennummern anspringt, kann ja sein ???
-
Wie wäre denn dieser ansatz:
data.seekg (0, ios::end); int fileCharsSigma = data.tellg(); data.seekg (0, ios::beg);Und jetzt könnte ich doch nach jedem getline die position nehmen oder?
-
Mal frage frage nebenbei;
Meine erste Zeile in der datei hat genau 72 zeichen. nach dem ersten getline gibt mir
int pos = data.tellg();pos = 77;
wo sind denn die 5 zeichen geblieben??
-
ismaild schrieb:
Meine erste Zeile in der datei hat genau 72 zeichen. nach dem ersten getline gibt mir
int pos = data.tellg();pos = 77;
wo sind denn die 5 zeichen geblieben??Ich vermute: BOM (4 Zeichen) + Zeile (72 Zeichen) + LF (1 Zeichen) = 77 Zeichen
-
Ja es scheint wirklich so zu sein. Das kuriose ist nun wenn man versucht die position 73 anzuspringen geht nicht.
seekg(74); ist bereits die neu zeile(also die 2.Zeile).
Nach einem getline(p1,p2) der ersten zeile gibt mir tellg() die 77, was ein kuddel muddel. wollte es nur mal erwähnt haben.....Aber wenn ich jetzt mir die position der Zweiten merke die ich mit getline bekommen habe und sie anspringe würden mir ja 3 Zeichen in der 2.zeile fehlen.
Ist den in jeder Datei dieses BOM drin.??
-
ismaild schrieb:
Wie wäre denn dieser ansatz:
data.seekg (0, ios::end); int fileCharsSigma = data.tellg(); data.seekg (0, ios::beg);Und jetzt könnte ich doch nach jedem getline die position nehmen oder?
wahrscheinlich eher vor(!) jedem 'getline', da Du diese Zeile später noch einmal lesen möchtest, oder?
Dann ist der Typ von pos bzw. fileCharSigma nicht (unbedingt) int, sondern std::istream::pos_type, auch wenn das dann als int implementiert ist.
Und warum immer noch 'getline'? Das Einlesen von csv-Dateinen hatten wir hier schon öfter.
-
Ich verstehe die aversion gegen getline nicht??
Ist doch ganz bequem so die Datei zeile für zeile zu parsen oder??
Vielleicht sehe ich jetzt den Wald vor lauter Bäume net.....
-
ismaild schrieb:
Ich verstehe die aversion gegen getline nicht??
Ist doch ganz bequem so die Datei zeile für zeile zu parsen oder??
Vielleicht sehe ich jetzt den Wald vor lauter Bäume net.....
Aversion ist das keine. getline ist ok, wenn man man Zeilen bzw. Strings bis zu einer Ende-Kennung lesen will. Ich unterstelle Dir aber, dass Du das gar nicht willst.
Werner_logoff schrieb:
ismaild schrieb:
@werner_logoff: wieso "Ich hoffe nicht" ???
weil getline doof ist.
.. hast Du den Beitrag nicht gelesen? insbesondere den letzten Absatz?
-
Doch den Beitrag habe ich gelesen,
aber ja eigentlich wollte ich die Datei zeilenweise durchlesen. Weil ne Datei mit einer million zeilen lese ich doch net komplett rein oder?
Im grunde genommen prüfe ich in jeder Zeile eine bestimmte Spalte, und jenachdem ob mein Kriterium erfüllt ist oder nicht wollte ich die Position speichern und net den ganzen Inhalt der Zeile.
ifstream contentfile(filename.c_str(), ios_base::in) while(getline(contentfile,std::string line)) { if(spalte(line,8) == std::string searchToken) speicherePos(....) }So in etwa sieht meine Logik aus!
-
Nicht komplett einlesen und auch nicht die Zeile lesen. Was willst Du mit der Zeile?
Was ich meine ist: wenn Du ein Kriterium aus der Datei haben willst, dann lese doch das Kriterium. Ich vermute mal, es handelt sich um einen String, der in der 8.Spalte steht, wobei Spalten immer mit ';' von einander getrennt sind.Dann sähe es so ähnlich aus:
ifstream contentfile(filename.c_str()); // ios_base::in ist unnötig, da (i)fstream for( string token; contentfile >> Spalte(8) >> token; contentfile.ignore( 999, '\n' ) ) { if( token == std::string(searchToken) ) speicherePos(....); }und 'Spalte' könnte so was sein:
struct Spalte // Manipulator zum Lesen bis zur Spalte mit der Nr 'spNr' in einer csv-Datei { // Bem.: spNr=1 ist die erste Spalte explicit Spalte( int spNr ) : m_spNr( spNr ) {} friend std::istream& operator>>( std::istream& in, const Spalte& s ) { for( int n = 1; in && n < s.m_spNr; ++n ) in.ignore( 999, ';' ); return in; } private: int m_spNr; };was hast Du mit den gespeicherten Positionen später vor?
-
hmmm interessanter ansatz.
Also nach dem ich das Kriterium geprüft und für mich verifiziert habe, wollte ich die zeile haben um so nur die in eine andere Datei zu schreiben die dem Kriterium entsprechen. Vorher wollte ich aber noch sortieren etc und so ein kram.
-
Also den token ziehe ich mir bisher so:
int getTokenInt( string line, char delim, int column ) { byte byDelimCounter=0; byte iCopyPposition(0); char * pc_line; string sToken; pc_line = new char [line.size()+1]; strcpy (pc_line, line.c_str()); for (unsigned short i = 0; pc_line[i]; i++) { char dfgdt = pc_line[i]; if(dfgdt == delim) { byDelimCounter++; } iCopyPposition=i; if(byDelimCounter == column) { while(pc_line[++iCopyPposition] != delim) sToken+=pc_line[iCopyPposition]; byDelimCounter++; } } std::stringstream ssStream(sToken); int iReturn; ssStream >> iReturn; return iReturn; }
-
Entschuldigung - jetzt habe wieder die Besonderheit der Strings vergessen. Jetzt kommt getline in's Spiel, da das Kriterium ein String ist!
In der zweiten Zeile des ersten Listings müsste es wohl heißen:for( string token; getline( contentfile >> Spalte(8), token, ';'); contentfile.ignore( 999, '\n' ) ).. oder sind die Strings noch in Hochkommata eingeschlossen?
-
was hat es den mit dieser meldung auf sich:
X:\path\projects\_stdc++\myProject\main.cpp|696|error: can't define friend function 'operator>>' in a local class definition|Nein keine Hochkommas.
-
Ok ich habe es aus der main gezogen ;o((
-
Wofür ist nochmal die 999 im Argument
for( string token; getline( contentfile >> Spalte(mySpalte), token, ';'); contentfile.ignore( 999, '\n' ) )
-
ismaild schrieb:
Wofür ist nochmal die 999 im Argument
for( string token; getline( contentfile >> Spalte(mySpalte), token, ';'); contentfile.ignore( 999, '\n' ) )Das ist die maximale Anzahl an Zeichen die übersprungen werden dürfen. Hier findest du eine Referenz, wo du solche Sachen selber nachschauen kannst:
www.cplusplus.comWerner_logoff meinte aber wahrscheinlich nicht wirklich die magische Zahl 999, sondern war nur zu schreibfaul für
std::numeric_limits<std::streamsize>::max().
-
Nur mal zum klarstellen türlich lese ich auch selber,
aber interaktiv finde ich das lernen viel besser aber trotzdem danke für dein hinweis
P.S.: Ich könnte mir ja auch ein Paar bücher kaufen.... jungs macht das forum zu.....