Wie kann ich variable Zahlen aus einer Zeile, die in einem Buffer ist, extrahieren?
-
Hallo Fill,
wie Kellerautomat schon sagte, wäre Schritt 1, eine Struktur
Eintrag(oder so) zu bauen, die sozusagen der Datensatz ist, der den Inhalt einer Zeile beschreibt. Für diesestruct Eintragbaue man sich die sogenannten Streaming-Operatoren und dort findet dann das eigentliche Lesen und Schreiben genau eines Eintrags statt.
In Deinem Fall ist es sicher angebracht, sich auf markante Zeichen in dem Text zu konzentrieren, die möglichst nur vor der jeweils nächsten Zahl auftauchen. Solche Stellen kann man mit der Methode ignore gezielt 'anspringen'.
Also bei "35.121**:** [Full GC (System) [PSYoungGen**:** 51172K->0K**(**764608K)] ... " ist das der ':' und die '('. Bei der zweiten Zahl (hier 51172K) muss man schon aufpassen, da der ':' bis dahin zweimal auftaucht.Ich habe das ganze hier mal skizziert:
#include <algorithm> // copy #include <fstream> #include <iterator> // i(o)stream_iterator #include <iostream> #include <limits> // numeric_limits struct Eintrag { static int const N = 10; double prefix_; int ps_[N]; }; // -- Streaming-Operator für das Lesen // 1 "35.121: [Full GC (System) // 2 [PSYoungGen: 51172K->0K(764608K)] // 3 [PSOldGen: 0K->50789K(1747648K)] // 4 51172K->50789K(2512256K) // 5 [PSPermGen: 73515K->73515K(147072K)], // .. Rest bis EOL" std::istream& operator>>( std::istream& in, Eintrag& e ) { const std::streamsize ALL = std::numeric_limits< std::streamsize >::max(); in >> e.prefix_; in.ignore( ALL, ':' ); // ersten ':' hinter 'prefix' überspringen const char* tags = ":(>(]>(:>("; const char* tag = tags; for( int i=0; i<Eintrag::N; ++i, ++tag ) in.ignore( ALL, *tag ) >> e.ps_[i]; return in.ignore( ALL, '\n' ); // Rest der Zeile überlesen } // -- Streaming-Operator für das Schreiben std::ostream& operator<<( std::ostream& out, const Eintrag& e ) { out << e.prefix_ << " "; std::copy( e.ps_, e.ps_ + Eintrag::N, std::ostream_iterator< int >( out, " " ) ); return out; } int main() { using namespace std; ifstream f1("test.txt"); ofstream f2("backtest.txt"); if( !f1.is_open() || !f2.is_open() ) { cerr << "Fehler beim Oeffnen einer der Dateien" << endl; return -2; } copy( istream_iterator< Eintrag >(f1), istream_iterator< Eintrag >(), ostream_iterator< Eintrag >(f2, "\n") ); return 0; }Gruß
WernerUps: SeppJ war schneller, aber ich habe alle Zahlen

@Edit: Schleife beim Lesen
-
Na ja aus den Zahlen wollte ich dann nachher eventuell ein kleines Diagramm zeichnen lassen.

Aber so weite Schritte kann ich nicht überblicken, daher wollte ich in kleinen Schritten vorrangehen.
Man hat mir auch schon gesagt das Java besser gewesen wäre, aber ich wollte halt was in c++ machen da ich java nicht kann um da etwas fitter zu werden und dan kam mir halt so eine "hirnrissige idee" mit dieser Datei

-
Ihr seid ja mal der Hammer ich doktor da Wochen dran rum und Ihr braucht 5 Minuten

irgendwie deprimiert das:)Auf jeden fall ma herzlichen Dank
-
FillColin schrieb:
Man hat mir auch schon gesagt das Java besser gewesen wäre, aber ich wollte halt was in c++ machen da ich java nicht kann um da etwas fitter zu werden und dan kam mir halt so eine "hirnrissige idee" mit dieser Datei

Mit Java hast du keine Vorteile - eher mit Python/Perl/Ruby oae.
-
zum Einlesen des Eintrags ist mir noch eine weit lustigere Variante eingefallen, als mein erster Vorschlag oben:
// -- Streaming-Operator für das Lesen // 1 "35.121: [Full GC (System) // 2 [PSYoungGen: 51172K->0K(764608K)] // 3 [PSOldGen: 0K->50789K(1747648K)] // 4 51172K->50789K(2512256K) // 5 [PSPermGen: 73515K->73515K(147072K)], // .. Rest bis EOL" std::istream& operator>>( std::istream& in, Eintrag& e ) { in >> e.prefix_; // +--- Zeichen für 'Zahl lesen' // |+-- lese bis zum folgenden Zeichen // || |3 |4 |5 const char* format = "%_:[_[_:%_(%_)_->%K(%K)]%K->%K(%K)[_:%K->%K(%K)]_\n"; int i=0; for( const char* p = format+2; *p; ++p ) *p == *format ? in >> e.ps_[i++]: *p == *(format+1)? in.ignore( std::numeric_limits< std::streamsize >::max(), *++p ): in >> check( *p ); return in; }Dazu braucht man noch die
struct check:struct check { check( char c ) : c_( c ) {} friend std::istream& operator>>( std::istream& in, check ch ) { char c; if( in >> c && c != ch.c_ ) in.setstate( std::ios_base::failbit ); return in; } private: char c_; };Die Variante ist sicherer, was den Syntax-Check angeht, und auch universeller einsetzbar.
Gruß
Werner
-
jetzt noch mit tmp? ist ja nicht viel anders als brainfuck... :p
-
Na ja mit dem letzten code kann ich mal gar nichts anfangen, da verbiegen sich bei mir die Hirnwindungen
, leider bin ich ja auch noch lange nicht so fit wie ihr 
_____________________________________________Aber hätte noch eine Frage???

Warum muss ich "FETT" das nochmal aufrufen und ohne File Angabe? Oder ist das nur ein Platzhalter?
copy( istream_iterator< Eintrag >(f1), istream_iterator< Eintrag >(), ostream_iterator< Eintrag >(f2, "\n") );
Werner Salomon schrieb:
Hallo Fill,
... copy( istream_iterator< Eintrag >(f1), istream_iterator< Eintrag >(), ostream_iterator< Eintrag >(f2, "\n") );...
-
FillColin schrieb:
Warum muss ich "FETT" das nochmal aufrufen und ohne File Angabe? Oder ist das nur ein Platzhalter?
copy( istream_iterator< Eintrag >(f1), istream_iterator< Eintrag >(), ostream_iterator< Eintrag >(f2, "\n") );
Das copy muss wisssen, bis wohin kopiert werden soll. Ein istream_iterator ohne Streamargument im Konstruktor steht für das Ende eines Streams. Siehe:
http://www.cplusplus.com/reference/std/iterator/istream_iterator/
http://www.cplusplus.com/reference/algorithm/copy/
-
FillColin schrieb:
Na ja aus den Zahlen wollte ich dann nachher eventuell ein kleines Diagramm zeichnen lassen.

Man hat mir auch schon gesagt das Java besser gewesen wäre, aber ich wollte halt was in c++ machen da ich java nicht kann um da etwas fitter zu werden und dan kam mir halt so eine "hirnrissige idee" mit dieser Datei

Du solltest uns etwas mehr über deine Ziele mitteilen.
Zahlenwerte aus einer Datei rauslesen, geht so gut wie mit jeder Programmiersprache und sogar mit Applikationen.Nimm eine Tabellenkalkulation Excel oder OpenOffice:
- Kann auch Diagramme erzeugen
- Kann strukturierte Text-Dateien einlesen
-
Nochmal Hallo,
alles funktioniert nun einwandfrei *freu*
--- Auf basis von "Werner Salomon" 22:41:49 05.07.2012---Nur hat meine Aufzeichnung nun einen "kritischen Wert" erreicht.
126032.403: [Full GC (System) [PSYoungGen: 2400K->0K(764608K)] [PSOldGen: 58257K->51512K(1747648K)] 60657K->51512K(2512256K) [PSPermGen: 81683K->81341K(82112K)], 0.3413080 secs] [Times: user=0.34 sys=0.00, real=0.34 secs]
Wenn nun mein Zeitstempel immer größer wird "FETT", dann ist nachher nur noch 126032 zu sehen. Der rest .403 wird verschluckt.
Nun habe ich versucht im Programm die Datentypen zu vergrößern also "long", dies hatte aber nicht den gewünschten Erfolg.
Dann habe ich mal etwas mit Zahlen gespielt
z.b. 200000000 der wird schön ausgegeben, aber sobald was mit Komma kommt schmeist der das weg z.B. 200000000.222Kann es sein, dass das Programm automatisch castet und rundet und wenn ja wie unterbinde ich das?
Scchöne Grüße
Fill
-
float und double sind mMn. denkbar schlechte Typen für Zeitstempel. Zumindest wenn der Zeitstempel exakt gespeichert/verarbeitet werden soll. Das geht mit float/double nämlich nur, wenn die binäre (!) Darstellung der Kommazahl ausreichend wenig signifikante Stellen hat.
Was noch dazukommt: je nach verwendeter Funktion (printf, operator << (ostream, ...), ...) werden floats/doubles per Default unterschiedlich genau formatiert. Und das kann eben dazu führen, dass Kommastellen die eigentlich da wären einfach nicht angezeigt werden.
Kann man natürlich alles mittels diverser Formatierungs-Optionen umstellen, aber es bleibt immer noch das Problem dass sich Dezimal-mit-Kommastellen nicht gut mit Binär-mit-Kommastellen verträgt.
-
Hallo Fill,
hustbaer hat wahrscheinlich recht mit seinem Verdacht, dass es sich nur um ein Darstellungsproblem handelt. Ein double reicht für 126032.403 locker aus.
Füge in meinem Listing vor dem 'copy( istream_iterator<>..' noch eine Formatierung für double ein:f2.precision(3); f2 << fixed; copy( istream_iterator< Eintrag >(f1), istream_iterator< Eintrag >(), ostream_iterator< Eintrag >(f2, "\n") );Damit erzwingst Du, dass double mit 3 Nachkommastellen ausgegeben wird.
Gruß
Werner
-
Danke für die thematisch Erörterrung!!
Sind diese Delauft-Werte in denen automatisch und unterschiedlich Formatiert wird eigentlich willkürlich ausgedachte Standardts oder entspricht das einer durchdachten Norm von c++.
Habe ich nur das Gefühl, dass das suboptimal ist oder ist meine Aufgabe eher Suboptimal

Dabei dachte ich das c++ mehr Vorgaben/-schriften bekommen hat wie C um es "sicherer/einfacher" zu machen und nun muss ich quasi doch so spitzfindig sein?

____________________________________________
Auf jeden fall super lieben Dank für die Komments bis jetzt, ihr habt mich echt weitergebracht und es macht sogar richtig spaß in diesem ForumGrüße
-
Der Anfangswert für precision ist laut Standard als 6 definiert.
-
FillColin schrieb:
Dabei dachte ich das c++ mehr Vorgaben/-schriften bekommen hat wie C um es "sicherer/einfacher" zu machen und nun muss ich quasi doch so spitzfindig sein?

Nein, du musst bloss den passenden Datentyp verwenden

-
Hallo, ich bin's wieder.
zu meiner Freude läuft das Programm auf basis von WERNER SALOMON (Thread 12:43:51 05.07.2012) einwandfrei und konnte es gut weiterverarbeiten.
Nun habe ich feststellen müssen, das in meine Textdatei 1 mal im Monat ein Sondereintag (Sonderprüfung) stadtfindet. Und zwar kein Full GC sondern nur ein CG
....
3636.211: [Full GC (System) [PSYoungGen: 6520K->0K(764608K)] [PSOldGen: 50789K->56413K(1747648K)] 57309K->56413K(2512256K) [PSPermGen: 82267K->82267K(172288K)], 0.3546920 secs] [Times: user=0.35 sys=0.00, real=0.36 secs]
7237.275: [GC [PSYoungGen: 91438K->2416K(764608K)] 147852K->58829K(2512256K), 0.0123960 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
7237.287: [Full GC (System) [PSYoungGen: 2416K->0K(764608K)] [PSOldGen: 56413K->58662K(1747648K)] 58829K->58662K(2512256K) [PSPermGen: 82381K->82381K(170048K)], 0.3349310 secs] [Times: user=0.33 sys=0.00, real=0.34 secs]
...Ab hier bricht das Programm dann ab

_____________________________________
Wie ich aus der Zeile GC meine gewünschten Zahlen herausbekomme weiß ich nun dank euch.Nur wie kann ich in das Programm einbauen, dass die Zeilen vorab geprüft werden ob ein FullGC oder ein GC vorliegt, um dann mit einem passenden Copy(...); darauf zu reagieren.
int main() { using namespace std; ifstream f1("test.txt"); ofstream f2("backtest.txt"); if( !f1.is_open() || !f2.is_open() ) { cerr << "Fehler beim Oeffnen einer der Dateien" << endl; return -2; } struc.precision(3); // 3 Nachkommastelen erzwingen struc << fixed; // Keine expot. Darstellung => Ganzzahl copy( istream_iterator< Eintrag >(f1), istream_iterator< Eintrag >(), ostream_iterator< Eintrag >(f2, "\n") ); return 0; }Habe mir überlegt, ob ich zwischen Zeile 10 und 14 irgendwie die Zeile Abfrage, dann prüfe und dann mit einer IF-Schleife in den passenden Coppy(..); gehe.
Aber ich muss das irgendwie immer Zeilenweise machen und nicht die gesammte Datei...hm...Hat mir eventuell jm. einen Gedankengang wie ich das umsetzen könnte?
Herzlichen Dank schon mal
Fill
-
FillColin schrieb:
Habe mir überlegt, ob ich zwischen Zeile 10 und 14 irgendwie die Zeile Abfrage, dann prüfe und dann mit einer IF-Schleife in den passenden Coppy(..); gehe.
Hallo Fill,
wenn Du eine Änderung machen willst (und das gilt immer bei Programmänderungen), so solltest Du zunächst feststellen, welches Modul/Funktion für diese Funktionalität, die Du ändern willst, verantwortlich ist.
Was Du hier vorhast, ist das Einlesen zu ändern. Das Einlesen geschieht im Streaming-Operator vonstruct Eintrag; also ist da die Baustelle, nirgendwo sonst.Wenn man die lustige Variante, die ich bereits gepostet habe, weiter entwickelt, so kann sie auch das.
#include <algorithm> // copy #include <fstream> #include <iterator> // i(o)stream_iterator #include <iostream> #include <limits> // numeric_limits #include <string> struct check { check( char c ) : c_( c ) {} friend std::istream& operator>>( std::istream& in, check ch ) { char c; if( in >> c && c != ch.c_ ) in.setstate( std::ios_base::failbit ); return in; } private: char c_; }; struct Eintrag { static int const N = 10; double time_; int ps_[N]; }; // -- Streaming-Operator für das Lesen // einiger(!) Logging Ausgaben des Garbage Collectors von Java // Bem.: PS := Parallel Scavenge (scavenge -> Reinigung) // // Format: (Beispiel, im Orginal einzeilig) // 35.121: // [Full GC (System) // [PSYoungGen: 51172K->0K(764608K)] // [PSOldGen: 0K->50789K(1747648K)] // 51172K->50789K(2512256K) // [PSPermGen: 73515K->73515K(147072K)], // .. Rest bis EOL // // -oder: // 7237.275: // [GC // [PSYoungGen: 91438K->2416K(764608K)] // 147852K->58829K(2512256K), // .. Rest bis EOL // std::istream& operator>>( std::istream& in, Eintrag& e ) { const std::streamsize ALL = std::numeric_limits< std::streamsize >::max(); std::string token; (in >> e.time_).ignore( ALL, '[' ) >> token; const char* format = token == "Full"? // +--- [0] Zeichen für 'Zahl lesen' // |+-- [1] lese bis zum folgenden Zeichen // ||+- [2] nächstes Element mit 0 belegen // ||| // |||<- Young --><- Old --><-- nn --><--- Perm ---> "%_#_[_:%K_(%K)][_>%K(%K)]%K->%K(%K)[_:%K->%K(%K)]_\n": // Full GC (System) "%_#_[_:%K_(%K)]" "##" "%K->%K(%K)" "###" "_\n"; // GC int* dst = e.ps_; for( const char* p = format+3; *p; ++p ) { if( *p == format[0] ) in >> *dst++; else if( *p == format[1] ) in.ignore( ALL, *++p ); else if( *p == format[2] ) *dst++ = 0; // Eintrag hier nicht vorhanden else in >> check( *p ); } return in; } // -- Streaming-Operator für das Schreiben std::ostream& operator<<( std::ostream& out, const Eintrag& e ) { out << e.time_ << " "; std::copy( e.ps_, e.ps_ + Eintrag::N, std::ostream_iterator< int >( out, " " ) ); return out; } int main() { using namespace std; ifstream f1("test.txt"); ofstream f2("backtest.txt"); if( !f1.is_open() || !f2.is_open() ) { cerr << "Fehler beim Oeffnen einer der Dateien" << endl; return -2; } copy( istream_iterator< Eintrag >(f1), istream_iterator< Eintrag >(), ostream_iterator< Eintrag >(f2, "\n") ); return 0; }beachte bitte, dass ich die gelesenen Zahlen nicht einfach in das Feld von
Eintragfülle, sondern zunächst noch zwei Elemente mit 0 belege. Das ist dann der fehlende Eintrag für das Feld[PSOldGen].
In den Zeilen 60 und 61 habe ich das Format fürFull GCundGCdefiniert.
Wenn Du dazu Fragen hast, so nur heraus damit.Gruß
Werner
-
Hallo Werner,
danke für die Antwort. Ich hatte zu beginn bewusst deine "lustige Variante" nicht genomme, da ich leider nur 40% davon verstanden habe. Also den "struct check" und den "streaming operator".
Wenn du mir allerdings anbietest meine Fragen dazu zu beantworten, dann werde ich ihn wohl einsetzen, weil ich grundsätzlich nur das verwenden will was ich auch verstehen und handhaben kann.
__________________________________
Ich würde mich bei den Zeilenangaben auf deinen letzten Post beziehen.8-20 Ich verstehe nicht warum nach dem friend(11) eine Schachtelung erfolgt und was diese bewirkt (12 u. 17)
18-19 Also private kenn ich, aber in der Form habe ich das noch nie eingesetzt. Sondern nur wenn ich ne Klasse private oder public gemacht habe. Daher erschließt sich mir der Teil nicht, da er mittem im struct ist.
54 Was bezweckt diese Zeile mit dem Gleich und dem Vergleich-Operator?
63-73 Ich kann mit zwar zusammenreimen was die Funktion macht und die Erklärung von dir bestätigt das auch, aber die Frage ist wie macht sie das.
In der for-schleife prüfst du ja ob % oder _ oder # vorhanden ist.
Pointer / Zeiger kenne ich zwar auch, aber da ich nicht so fit bin verbiegt es hier meine Hirnwindungen
Und allgemein, bzum Leseoperator.
Betrachtet er eine Zeile und springt dann in die nächste ? (wenn ja wie? wo? oder macht das die for schleife)
Oder geht er das Dokument auf einmal durch und merkt dann wenn die Zeile zuende ist?
_____________________________________________
Es tut mir sehr leid wenn ich so viele Fragen stelle, leider ist dieser Programmcode doch zu hoch für mich, um ihn in seiner Gesammtheit zu überschauen.Auf jeden Fall herzlichen Dank für die Mühe deinerseits
Grüße
Fill
-
FillColin schrieb:
8-20 Ich verstehe nicht warum nach dem friend(11) eine Schachtelung erfolgt und was diese bewirkt (12 u. 17)
Die Schachtelung kommt von der Funktion die in Zeile 11 anfängt. Das friend bezieht sich auf diese Funktion. Die Funktion hat einen etwas ungewöhnlichen Namen, operator>>, ist aber ansonsten eine Funktion wie jede andere auch. Der ungewöhnliche Name macht, dass man sie später auch mittels
istreamobjekt >> checkobjekt;aufrufen kann, anstatt nur mit
operator>>(istreamobjekt, checkobjekt);. Das nennt man Operatorüberladung.
Beachte, dass die Funktion kein Member von check ist. Das friend macht an dieser Stelle nicht nur, dass die Funktion auf die privaten Member von check zugreifen kann, sondern auch, dass sie frei im Namensraum von check liegt, obwohl sie in check definiert wird.
18-19 Also private kenn ich, aber in der Form habe ich das noch nie eingesetzt.
Dann kennst du private nicht wirklich, denn hier hat es genau die gleiche Bedeutung wie anderswo, denn es gibt nur eine Bedeutung.
Sondern nur wenn ich ne Klasse private oder public gemacht habe.
Man kann keine Klassen private oder public machen, sondern nur gewisse Member. Verwirrt dich das struct? struct und class sind in C++ das gleiche, einziger(!) Unterschied ist, bei class ist alles private, sofern man es nicht public macht, bei struct ist alles public, solange man es nicht private macht. (Oder protected, was ich jetzt mal unterschlagen habe, ist überall noch eine dritte Möglichkeit)
Daher erschließt sich mir der Teil nicht, da er mittem im struct ist.
Dann hast du private und public wirklich nicht verstanden. Da check ein struct ist, ist alles was vor dem private steht public, das ist in diesem Fall nur der Konstruktor in Zeile 10 (der friend in Zeile 11 ist sowieso keine Memberfunktion und nicht betroffen von public/private, siehe oben). Alles nach dem private ist private, also der Member c_ ist von außen unsichtbar.
54 Was bezweckt diese Zeile mit dem Gleich und dem Vergleich-Operator?
Das ist eine Zeile bis einschließlich 62.
Du kennst den ternären Operator?
a = b ? c : d;Das ist eine andere Schreibweise für
if (b) a = c; else a = d;Da steht also:
if (token == "Full"?) format = "%_#_[_:%K_(%K)][_>%K(%K)]%K->%K(%K)[_:%K->%K(%K)]_\n"; else format = "%_#_[_:%K_(%K)]" "##" "%K->%K(%K)" "###" "_\n";63-73 Ich kann mit zwar zusammenreimen was die Funktion macht und die Erklärung von dir bestätigt das auch, aber die Frage ist wie macht sie das.
In der for-schleife prüfst du ja ob % oder _ oder # vorhanden ist.
Pointer / Zeiger kenne ich zwar auch, aber da ich nicht so fit bin verbiegt es hier meine Hirnwindungen
Ich behaupte mal, wenn ich es dir erkläre, verstehst du es nicht oder die Erklärung wird lang wie ein Lehrbuch. Daher: Lies erst einmal ein Lehrbuch, bis du weißt, wie die Streams funktionieren und ein bisschen über Pointerarithmetik. Wichtig ist, dass es ein gutes Buch ist, sonst werden die Streams nicht richtig erklärt (dafür wird aber wahrscheinlich viel zu viel Gewicht auf Pointer gelegt :p ). Siehe zweiter Link in meiner Signatur.
Und allgemein, bzum Leseoperator.
Welchem? Der Code definiert gerade zwei eigene Operatoren, die jeweils unzählige verschiedene andere Leseoperatoren benutzen. Ich nehme mal an, du meinst den in Zeile 49:
Betrachtet er eine Zeile und springt dann in die nächste ? (wenn ja wie? wo? oder macht das die for schleife)
Er liest so lange, wie das Format stimmt. Da das Format mit einem Zeilenumbruchzeichen endet (siehe Zeilen 61 und 62), wird er bei Erfolg eine ganze Zeile gelesen haben. Bei Misserfolg wird er irgendwo stehen bleiben. Er endet aber nicht prinzipbedingt auf dem Zeilenende, sondern wirklich nur wegen des Formatstrings der hier so gegeben ist. Zeilenumbrüche sind keine besonderen Zeichen für den Computer, die Sonderrolle die du ihnen zusprichst kommt allein aus ihrer üblichen Darstellung auf dem Bildschirm.
-
Man kann keine Klassen private oder public machen, sondern nur gewisse Member. Verwirrt dich das struct?
Voll verwirrt, aber ich habe es noch einmal nachgelesen. Ich habe hier wohl einige sachen durcheinander gebracht.
Ein gutes Buch habe ich schon "c++ von A-Z von Jürgen Wolf" und sogar in Hardwareform:)
Das ist eine Zeile bis einschließlich 62.
if (b)
a = c;
else
a = d;
klar kenn ich das
das hätte ich aber nie erkannt
wie blöd kann man sein
vor lauber Bäumen sieht man den Wald nicht mehr
habe leider noch nicht so das geschulte Auge, sorryDas hat mich schon mal super weiter gebracht vielen Dank, da kommt gleich licht in's dunkel

63-73 Ich kann mit zwar zusammenreimen was die Funktion macht und die Erklärung von dir bestätigt das auch, aber die Frage ist wie macht sie das.
Und wieder geht mir ein Licht auf. C kann ich ja etwas besser wie C++ nun habe ich herausgefunden das in C++ pointer anderster geschrieben werden wie in C. Also z.b. char* format bzw. char *format...das war der Grund wieso ich das nicht verstanden habe

Also nun blicke ich langsam durch, danke für die Mühen mir da weiter zu helfen.
_________________________________________________
Nun noch eine Frage, bei der ich noch keine 100% Antwort gefunden habe wie das der Code macht.
Also:
Meine Zeile 95 ist ja mein copy, welches die f1 in die datei f2 kopiert, mit dem Zahlenselektiervorgang im istream (Zeile 49)Soweit so gut.
Ich verstehe noch immer nicht woher das Programm weiß, dass wann und wo eine Zeile zuende ist, bzw. er eine Neue anfangen muss.
Klar /n kenne ich und es ist ein Zeichen wie jedes andere.
Die Frage ist auch schwer zu formulieren, tut mir leid ich versuche es etwas Bildhafter.Ich stelle mir immer vor, dass es eine Schleife ist, in der nur eine Zeile gelesen wird z.B. über getline. Diese wird dann abgearbeitet und dann beginnt die Schleife nach prüfung ob noch weitere Zeilen vorhanden sind erneut eine ein zu lesen und zu bearbeiten...usw.. bis keine mehr vorhanden sind. (eventuell zu nahe an der C Programmierung) aber so stelle ich mir das vor.
Das ist ja aber in diesem Programm so nicht der Fall?! oder für mich nicht erkennbar.Hat das etwas mit dem struct "Eintrag" zu tun mit int const N=10 und dem double time? Weil das würden ja dann meine 11 Werte ergeben. Und wenn diese bedient sind wendert er den struct "Eintrag" erneut an nach dem oder vordem er Rausgeschrieben hat? Liege ich da mit der denkweise richtig?
Puh ich hoffe ich konnte mich irgendwie verständlcih machen. Und es tut mir leid wenn ich euch eventuell mit solchen Grundlagen maltretiere.
Dennoch herzlichen Dank, auf jedenfall macht es mir Spaß etwas Zeit in die Programmierung zu stecken.
Grüße