Chars zusammenfügen und sortieren
-
jap. wie gesagt, ich hab damals inner uni c gelernt und hab mir das Buch von Heiko kalista zu c++ geholt. gesehen hab ichs schon mal, aber leider noch nicht wirklich mit gearbeitet.
Was das einlesen angeht: genau da liegt ja das proglem. Wenn ich die Datei vor beginn der ersten Schleife einlese, dann kann ich die innere Schleife ein mal bis zum ende durchlaufen lassen.
Danach scheint es einen Fehler in dem container zu geben und ich bekomme nurnoch Herzchen und so nen quatsch ausgegeben...Meine Vermutung ist einfach, dass die Datei bis zum Ende durchlaufen wird und der Zeiger dann auf dem letzten Zeichen steht, daher wird Die Schleife direkt abgebrochen, da ja Das Dateiende erreicht ist. Der Versuche mit der ausge-// Zeile mit file.seekg(0, ios::beg()); hat leider keinen Unterschied gebracht.
-
campinge schrieb:
jap. wie gesagt, ich hab damals inner uni c gelernt und hab mir das Buch von Heiko kalista zu c++ geholt. gesehen hab ichs schon mal, aber leider noch nicht wirklich mit gearbeitet.
Ist ja nicht so schlimm.

Wenn du mal Zeit hast, kannst du dir ja die C++-Varianten etwas genauer anschauen. Vielleicht gibts da das eine oder andere Erlebnis à la "Ah, das geht doch viel einfacher..."
campinge schrieb:
Was das einlesen angeht: genau da liegt ja das proglem. Wenn ich die Datei vor beginn der ersten Schleife einlese, dann kann ich die innere Schleife ein mal bis zum ende durchlaufen lassen.
Danach scheint es einen Fehler in dem container zu geben und ich bekomme nurnoch Herzchen und so nen quatsch ausgegeben...Hmm... Bei den C++-Streams gibt es eben Fehlerflags, die anzeigen, wenn etwas nicht mehr geht. Sobald eines dieser Flags gesetzt ist, funktionieren Operationen auf dem Stream nicht mehr. EOF (End Of File) ist eines dieser Flags, das kannst du mit
eof()abfragen. Oder sonst mitgood(), ob alles in Ordnung ist. Mitclear()setzt du die Fehlerflags zurück.Ich würde vorschlagen, du schaust mal im Debugger oder mit Konsolenausgaben, bis wohin der Stream okay ist, und ob/wo die Flags gesetzt werden.
-
Man kann Files auch in C überprüfen.
feof, um abzufragen, ob ein File das Ende erreicht hat und clearerr um die Flags wieder zurückzusetzen.
Dann sollte das auch mit dem fsetpos wieder funktionieren.Wenn du das aber so machst, dann ab mit dir ins C-Unterforum.

-
Nexus hat völlig Recht. Mit string und fstream lässt sich das Programm mit Sicherheit wesentlich vereinfachen (auch wenn ich nicht alles verstanden habe).
Darüber hinaus würde ich Dir empfehlen, für den Inhalt einer Zeile eine Struktur zu modellieren. Die kann man dann besser handeln.
Das sähe dann so ähnlich aus wie folgendes:#include <algorithm> // sort #include <iostream> #include <fstream> #include <string> #include <deque> struct Entry // steht für einen Eintrag in der Datei { bool operator<( const Entry& b ) const // legt die Reihenfolge bei 'sort' fest { return m_fix < b.m_fix; } std::string m_fix; double m_latitude; double m_longitude; }; std::istream& operator>>( std::istream& in, Entry& e ) { // lese 'fix', ignoriere 6 Zeichen, lese 'latitude' und 'longitude' return (in >> e.m_fix).ignore( 6 ) >> e.m_latitude >> e.m_longitude; } std::ostream& operator<<( std::ostream& out, const Entry e ) { // Ausgabe im neuen Format // z.B.: ENTRE;-31.534170;130.949200 return out << e.m_fix << ';' << e.m_latitude << ';' << e.m_longitude; } int main() { using namespace std; deque< Entry > fx_Entries; ifstream fx_fwpNavFIX("navdata/wpNavFix.txt"); for( Entry e; fx_fwpNavFIX >> e; ) { // if( e steht in "navigation/Fixes.db" ) fx_Entries.push_back( e ); } sort( fx_Entries.begin(), fx_Entries.end() ); ofstream fx_OutFile("navigation_new/Fixes.db"); for( deque< Entry >::iterator e = fx_Entries.begin(); e != fx_Entries.end(); ++e ) { int number = 0; // ?? fx_OutFile << *e << ';' << number << endl; } return 0; }Gruß
Werner
-
Guten Morgen zusammen
Vielen Danke erstmal für die Super Hilfestellungen.
Ich werde mich heute mal Werner's Beispiel widmen und mal versuchen mein Programm umzuschreiben.
Auch die Strings werde ich mir noch einmal zu herzen nehmen. Die scheinen ja doch eine ziemliche Arbeitsentlastung zu sein.Wo der o.g Fehler genau auftritt weis ich mittlerweile auch:
Der Erste Fixpunkt hat keinen übereinstimmenden Treffer in der zu überprüfenden Liste, daher läuft die Vergleichsschleife einmal bis zum Ende durch.
Das Programm arbeitet weiter und pusht den ersten Eintrag in meinen Container.
Beim 2. Fixpunkt und dem Start der Vergleichsschleife wird mit dem letzten Punkt der Liste, also der "Abbruchsbedingung" begonnen. Dementsprechend wird fx_checksum wirder auf true gesetzt und die Schleife beendet. Genau in diesem Moment wird auch der Inhalt des vorherigen Schleifendurchlaufs mit an fx_chLonglitude drangehängt, wobei mein char[11] zu einem char[39] wird. das führt weiter unten zu einem Speicherüberlauf und dem Abbruch des Programms. Lösche in nun das angehängte manuell raus, so geht das dann relativ fix mit allen Punkten weiter. Nach ~2min ist dann alles fertig und die Datei wird beschrieben...Wenn ich jetzt vor jedem Schleifenaufruf die Datei in fx_InFile1 neu einlese, dann läuft die innere Schleife komplett durch...
Naja, aber jetzt mal schauen, was passiert, wenn ich den Ständigen Wechsel von string -> char ausbaue und nurnoch mit strings arbeite...
*Ich komme wieder*

-
ok, und da bin ich auch schon wieder. Sorry, für den Doppelpost.
Ich habe mich heute im Zug mal kräftig mit Werner's Beispiel auseinandergesetzt und versucht es nachzuvollziehen. dann habe ich selber versucht ein paar sachen Hinzuzufügen, das klappt aber noch nicht soo ganz. hier mal "mein" code:
#include <algorithm> // sort #include <iostream> #include <fstream> #include <string> #include <deque> struct Entry // Struktur für das Eingangsfile { bool operator<( const Entry& b ) const // legt die Reihenfolge bei 'sort' fest { return m_fix < b.m_fix; } std::string m_fix; // String für das Fix double m_latitude; // bool für Latitude double m_longitude; // bool für longlitude }; struct Compare // Strukur für das Vergleichsfile { bool operator<( const Compare& b ) const // legt die Reihenfolge bei 'sort' fest { return m_fix < b.m_fix; } std::string m_fix; // String für das Fix double m_latitude; // bool für latitude double m_longitude; // bool für longlitude int m_Number; // int für die nummer }; //----------------------------------------------------------- // Was machen die hier genau? Einlesen und formatieren? //----------------------------------------------------------- std::istream& operator>>( std::istream& in, Entry& e ) // Lesen { // lese 'fix', ignoriere 6 Zeichen, lese 'latitude' und 'longitude' return (in >> e.m_fix).ignore( 6 ) >> e.m_latitude >> e.m_longitude; } std::ostream& operator<<( std::ostream& out, const Entry e ) // Formatieren { // Ausgabe im neuen Format // z.B.: ENTRE;-31.534170;130.949200 return out << e.m_fix << ';' << e.m_latitude << ';' << e.m_longitude; } std::istream& operator>>( std::istream& in, Compare& f ) // Lesen { // lese 'fix', 'latitude', 'longitude' und 'fix' return in >> f.m_fix >> f.m_latitude >> f.m_longitude >> f.m_fix; } int ExportFixes() { using namespace std; deque< Entry > fx_Entries; // Container mit Struktur "Entry" erstellen deque< Compare > fx_Compare; std::ifstream fx_fwpNavFIX("navdata/wpNavFIX.txt"); // Input- Datei wpNavFix definieren std::ifstream fx_fFixes("navigation/Fixes.db"); // Input-Datei Fixes definieren for( Entry e; fx_fwpNavFIX >> e; ) // Einträge von Entry durchlaufen { fx_Entries.push_back( e ); // e in fx_Entries einfügen } for( Compare f; fx_fFixes >> f; ) // Einträge von Entry durchlaufen { fx_Compare.push_back( f ); } sort( fx_Entries.begin(), fx_Entries.end() ); // fx_Entries sortieren ofstream fx_OutFile("navigation_new/Fixes.db"); // Ausgabedatei definieren for( deque< Entry >::iterator e = fx_Entries.begin(); e != fx_Entries.end(); ++e ) //fx_Entries durchlaufen { for( deque< Compare >::iterator f = fx_Compare.begin(); f != fx_Compare.end(); ++f ) //fx_Compare durchlaufen { if (*e.m_Fix == *f.m_Fix && *e.m_Fix[0] != ';') // wenn Eintrag gefunden { fx_OutFile << *e << ';' << *f.m_Number << endl; // Schreibe in Datei } else if (f == fx_Entries.end() && *e.m_Fix[0] != ';') // Wenn Fileend { fx_OutFile << *e << ';' << '5' << endl; // 5 dranhängen } } } return (true); }1. Was genau ist die variable "e" jetzt. sie wird zwar oben als const e deklariert, aber als const - was?
2. Die Zeilen werden ja in fx_Entries eingelesen, mit der Struktur von entry, richtig? Wie kann ich dann auf die Variable m_Fix von Entry zugreifen? Ich hab's jetzt einfach mal mit *e.m_Fix probiert, das scheint aber gnadenlos falsch zu sein, sagt mir zumindest der Compiler

3. In der Ursrungsdatei gibt es einige Header-Zeilen, die mit einem ';' beginnen. Wie kann ich die ausschließen? -- Selbiges für die Vergleichsdatei, nur mit '/'
Vielen Dank schon- und Nochmal für eure bisherigen bemühungen. Vielleicht blicke ich ja doch noch dur c++ durch

-
1. Welches meinst du? Du hast zwei:
for( deque< Entry >::iterator e = fx_Entries.begin();und:
for( Entry e; fx_fwpNavFIX >> e; )Und bei beiden steht der Typ.

2. Fast. Das ist ein Iterator:
enweder so:(*e).m_Fixoder:
e->m_Fix
-
campinge schrieb:
3. In der Ursrungsdatei gibt es einige Header-Zeilen, die mit einem ';' beginnen. Wie kann ich die ausschließen? -- Selbiges für die Vergleichsdatei, nur mit '/'
Du kannst prüfen, ob das erste Zeichen ein solches ist, wenn ja, überspringst du die Zeile (d.h. du liest sie z.B. mit
std::getline(), aber speicherst sie nirgends).
-
campinge schrieb:
3. In der Ursrungsdatei gibt es einige Header-Zeilen, die mit einem ';' beginnen. Wie kann ich die ausschließen? -- Selbiges für die Vergleichsdatei, nur mit '/'
Du kannst vor jedem Einlesen eines Eintrags prüfen ob ein ';' vorangestellt ist und falls ja die Zeile ignorieren.
Eine Möglichkeit, dies zu integrieren, besteht darin, die Einlese-Routine von Entry zu erweitern:
std::istream& operator>>( std::istream& in, Entry& e ) // Lesen { // prüfe zunächst auf Kommentarzeilen und // lese 'fix', ignoriere 6 Zeichen, lese 'latitude' und 'longitude' while( in >> std::ws && !in.eof() && char(in.peek()) == ';' ) // solange ein ';' folgt .. in.ignore( 9999, '\n' ); // ..überlese bis Zeilenende return (in >> e.m_fix).ignore( 6 ) >> e.m_latitude >> e.m_longitude; }Zur Erklärung. Das in >> std::ws überliest zunächst alle white space Zeichen (ws). Dies ist notwendig, da peek wirklich nur das nächste Zeichen anschaut und dies könnte ja auch ein Leerzeichen oder Zeilenende sein, aber diese interessieren ja nicht. Die Prüfung auf !in.eof() sorgt dann dafür, dass peek nicht mit EOF (d.h. End Of File) aufgerufen wird, da es sonst ein EOF zurückgibt und der cast nach char nicht sauber wäre. Und schließlich wird mit in.peek() das nächste Zeichen angesehen - OHNE es zu lesen! D.h. es fehlt kein Zeichen beim nächsten Einlesen in 'in >> e.m_fix', falls es kein ';' war und die while-Schleife beendet wurde.
Die zweite Möglichkeit besteht darin, das 'Kommentar überlesen' in einen sogenannten Manipulator zu packen und diesen dann aufzurufen. Der sieht so aus:
std::istream& comment( std::istream& in ) // überliest Kommentar beginnend mit ';' { while( in >> std::ws && !in.eof() && char(in.peek()) == ';' ) in.ignore( 999, '\n' ); return in; }und könnte dann so in Zeile 55 Deines Programms integriert werden
for( Entry e; fx_fwpNavFIX >> comment >> e; ) // (55) Einträge von Entry durchlaufen { fx_Entries.push_back( e ); // e in fx_Entries einfügen }Gruß
Werner
-
Hey, vielen Dank!
Ich habs doch tatsächlich noch geschafft das Programm zum laufen zu bringen.
-Allerdings nicht so, wie geplant...Irgendwie scheint das Einlesen nicht so richtig zu funktionieren. Es wird der Erste wegpunkt eingelesen und dann wars das auch schon, der Rest bleibt 'quasi' leer. Die letzte Schleife wird aufgerufen, aber direkt beendet. Auch Testausgaben innerhalbder Schleifen wurden übersprungen. Jetzt bin ich total verwirrt...
Ich stelle euch hier mal ein paar Auszüge aus den Dateien rein und den Programmcode. Es wäre super, wenn das einer von euch mal durch den compiler jagen könnte um herauszufinden was da genau schief geht...
"navdata/wpNavFIX.txt"
;Commentlinie SPOLE SPOLE-90.000000 0.000000 89W80 89W80-89.000000-180.000000 89W79 89W79-89.000000-179.000000 89W78 89W78-89.000000-178.000000 89W77 89W77-89.000000-177.000000 89W76 89W76-89.000000-176.000000 89W75 89W75-89.000000-175.000000 89W74 89W74-89.000000-174.000000 89W73 89W73-89.000000-173.000000 89W72 89W72-89.000000-172.000000 89W71 89W71-89.000000-171.000000 89W70 89W70-89.000000-170.000000"navigation/Fixes.db"
//commentline 00MKK;22.528056;-156.170961;3 00UPP;20.566668;-154.125;3 03MCT;55.136667;-7.191389;1 03SML;25.61;30.635278;3 04THT;73.147778;-68.683056;3 06TRA;47.733334;8.283334;4 08YBK;63.751277;-100.000685;3 15SNT;40;-16;3 16DEL;30.840107;-105.380861;1 16YYQ;60.77426;-99.999245;1 17AST;26.330833;29.001667;3 1F;47.630556;-65.744722;2 21YQL;49.00746;-109.73596;1 21YZS;61.566959;-89.049881;2 22SNT;45;-14;3 247PQ;33.75;165;3 24DUB;55.0875;-8.569722;1 24VLS;-15.186667;28.825556;2 251PQ;35.535231;149.995961;3 25VLS;-15.616944;28.107778;3 27VLS;-14.973056;28.7075;3Programm:
#include <algorithm> // sort #include <iostream> #include <fstream> #include <string> #include <deque> struct Entry // Struktur für das Eingangsfile { bool operator<( const Entry& b ) const // legt die Reihenfolge bei 'sort' fest { return m_fix < b.m_fix; } std::string m_fix; // String für das Fix double m_latitude; // bool für Latitude double m_longitude; // bool für longlitude }; struct Compare // Strukur für das Vergleichsfile { bool operator<( const Compare& b ) const // legt die Reihenfolge bei 'sort' fest { return m_fix < b.m_fix; } std::string m_fix; // String für das Fix double m_latitude; // bool für latitude double m_longitude; // bool für longlitude int m_Number; // int für die nummer }; std::istream& operator>>( std::istream& in, Entry& e ) // Lesen { // lese 'fix', ignoriere 6 Zeichen, lese 'latitude' und 'longitude' return (in >> e.m_fix).ignore( 6 ) >> e.m_latitude >> e.m_longitude; } std::ostream& operator<<( std::ostream& out, const Entry e ) // Formatieren { // Ausgabe im neuen Format // z.B.: ENTRE;-31.534170;130.949200 return out << e.m_fix << ';' << e.m_latitude << ';' << e.m_longitude; } std::istream& operator>>( std::istream& in, Compare& f ) // Lesen { // lese 'fix', 'latitude', 'longitude' und 'fix' return in >> f.m_fix >> f.m_latitude >> f.m_longitude >> f.m_fix; } std::istream& comment( std::istream& in ) // überliest Kommentar beginnend mit ';' { while( in >> std::ws && !in.eof() && char(in.peek()) == ';' ) in.ignore( 999, '\n' ); return in; } std::istream& comment2( std::istream& in ) // überliest Kommentar beginnend mit ';' { while( in >> std::ws && !in.eof() && char(in.peek()) == '/' ) in.ignore( 999, '\n' ); return in; } int ExportFixes() { using namespace std; deque< Entry > fx_Entries; // Container mit Struktur "Entry" erstellen deque< Compare > fx_Compare; std::ifstream fx_fwpNavFIX("navdata/wpNavFIX.txt"); // Input- Datei wpNavFix definieren std::ifstream fx_fFixes("navigation/Fixes.db"); // Input-Datei Fixes definieren for(Entry e; fx_fwpNavFIX >> comment >> e; ) // Einträge von Entry durchlaufen { fx_Entries.push_back( e ); // e in fx_Entries einfügen } for( Compare f; fx_fFixes >> comment2 >> f; ) // Einträge von Entry durchlaufen { fx_Compare.push_back( f ); } sort( fx_Entries.begin(), fx_Entries.end() ); // fx_Entries sortieren ofstream fx_OutFile("navigation_new/Fixes.db"); // Ausgabedatei definieren for( deque< Entry >::iterator e = fx_Entries.begin(); e != fx_Entries.end(); ++e ) //fx_Entries durchlaufen { for( deque< Compare >::iterator f = fx_Compare.begin(); f != fx_Compare.end(); ++f ) //fx_Compare durchlaufen { if ( e->m_fix == f->m_fix && e->m_fix[0] != ';' ) // wenn Eintrag gefunden { fx_OutFile << *e << ';' << f->m_Number << endl; // Schreibe in Datei } else if ( f == fx_Compare.end() ) // Wenn Fileend { fx_OutFile << *e << ';' << '5' << endl; // 5 dranhängen } } } return (true); }
-
campinge schrieb:
Irgendwie scheint das Einlesen nicht so richtig zu funktionieren. Es wird der Erste wegpunkt eingelesen und dann wars das auch schon, der Rest bleibt 'quasi' leer. ...
Beim Einlesen ist das Format der einzulesenden Datei das A und O. Es dauert immer ein wenig, bis man es aus den Leuten herausbekommen hat

Du schriebst am 11.1.:
campinge schrieb:
die Datei sieht in etwa so aus:
`ENTRE ENTRE-31.534170 130.949200
PEA83 PEA83-31.533961 115.952714
89W80 89W80-89.000000-180.000000
`
und jetzt:
campinge schrieb:
"navdata/wpNavFIX.txt"
;Commentlinie SPOLE SPOLE-90.000000 0.000000 89W80 89W80-89.000000-180.000000 89W79 89W79-89.000000-179.000000 89W78 89W78-89.000000-178.000000ist das gleiche, sieht aber anders aus

Ich habe Die Einlesefunktion von 'Entry' noch mal geändert, so dass sie mit beliebig vielen white space Zeichen zwischen den ersten beiden (Fix-)Worten zurechtkommt.
Das gleiche gilt für das Format der Compare-Datei.
campinge schrieb:
std::istream& operator>>( std::istream& in, Compare& f ) // Lesen { // lese 'fix', 'latitude', 'longitude' und 'fix' return in >> f.m_fix >> f.m_latitude >> f.m_longitude >> f.m_fix; }aber:
campinge schrieb:
"navigation/Fixes.db"
//commentline 00MKK;22.528056;-156.170961;3 00UPP;20.566668;-154.125;3 03MCT;55.136667;-7.191389;1also ist der Kommentar oben glatt gelogen
- korrekt wäre:{ // lese 'fix' bis';', 'latitude', ';', 'longitude', ';' und 'nummer'Ich habe beides angepasst, ein wenig umstrukturiert, damit es nicht so durcheinander erscheint und noch den find-Algorithmus von C++ eingebaut.
#include <algorithm> // sort, find #include <iostream> #include <fstream> #include <string> #include <deque> // -- Helferlein zum Einlesen eines erwarteten Zeichens template< char C > std::istream& Char( std::istream& in ) { char c; if( in >> c && c != C ) in.setstate( std::ios_base::failbit ); return in; } struct Entry // Struktur für das Eingangsfile { bool operator<( const Entry& b ) const // legt die Reihenfolge bei 'sort' fest { return m_fix < b.m_fix; } std::string m_fix; // String für das Fix double m_latitude; // bool für Latitude double m_longitude; // bool für longlitude }; struct Compare // Strukur für das Vergleichsfile { explicit Compare( const std::string& fix = std::string() ) // Konstruktor für Vergleiche : m_fix( fix ) , m_latitude(), m_longitude() , m_Number() {} bool operator<( const Compare& b ) const // legt die Reihenfolge bei 'sort' fest { return m_fix < b.m_fix; } bool operator==( const Compare& b ) const { return m_fix == b.m_fix; } std::string m_fix; // String für das Fix double m_latitude; // bool für latitude double m_longitude; // bool für longlitude int m_Number; // int für die nummer }; bool operator!=( const Compare& a, const Compare& b ) { return !(a == b); } std::istream& operator>>( std::istream& in, Entry& e ) // Lesen { // lese 'fix', ab nächsten char 5 Zeichen ignorieren, lese 'latitude' und 'longitude' return (in >> e.m_fix >> std::ws).ignore( 5 ) >> e.m_latitude >> e.m_longitude; } std::ostream& operator<<( std::ostream& out, const Entry e ) // Formatieren { // Ausgabe im neuen Format // z.B.: ENTRE;-31.534170;130.949200 return out << e.m_fix << ';' << e.m_latitude << ';' << e.m_longitude; } std::istream& operator>>( std::istream& in, Compare& f ) // Lesen { // lese 'fix' bis';', 'latitude', ';', 'longitude', ';' und 'nummer' // z.B.: 00MKK;22.528056;-156.170961;3 return std::getline( in, f.m_fix, ';' ) >> f.m_latitude >> Char<';'> >> f.m_longitude >> Char<';'> >> f.m_Number; } std::istream& comment( std::istream& in ) // überliest Kommentar beginnend mit ';' { while( in >> std::ws && !in.eof() && char(in.peek()) == ';' ) in.ignore( 999, '\n' ); return in; } std::istream& comment2( std::istream& in ) // überliest Kommentar beginnend mit '/' { while( in >> std::ws && !in.eof() && char(in.peek()) == '/' ) in.ignore( 999, '\n' ); return in; } int ExportFixes() { using namespace std; deque< Entry > fx_Entries; // Container mit Struktur "Entry" erstellen { std::ifstream fx_fwpNavFIX("navdata/wpNavFIX.txt"); // Input- Datei wpNavFix definieren for(Entry e; fx_fwpNavFIX >> comment >> e; ) // Einträge von Entry durchlaufen { fx_Entries.push_back( e ); // e in fx_Entries einfügen } sort( fx_Entries.begin(), fx_Entries.end() ); // fx_Entries sortieren } deque< Compare > fx_Compare; { std::ifstream fx_fFixes("navigation/Fixes.db"); // Input-Datei Fixes definieren for( Compare f; fx_fFixes >> comment2 >> f; ) // Einträge von Entry durchlaufen { fx_Compare.push_back( f ); } } ofstream fx_OutFile("navigation_new/Fixes.db"); // Ausgabedatei definieren for( deque< Entry >::iterator e = fx_Entries.begin(); e != fx_Entries.end(); ++e ) //fx_Entries durchlaufen { // -- alle Einträge aus 'navdata/wpNavFIX.txt' sortiert wegschreiben // hinter jeden Eintrag wird die Zahl geschrieben, die in 'navigation_new/Fixes.db' für diesen Eintrag // gefunden wurde. Falls keiner gefunden wurde, so wird eine '5' angehängt. fx_OutFile << *e << ';'; deque< Compare >::iterator f = find( fx_Compare.begin(), fx_Compare.end(), Compare( e->m_fix ) ); if( f != fx_Compare.end() ) fx_OutFile << f->m_Number; // Nummer aus 'navigation_new/Fixes.db' für diesen Eintrag anhängen else fx_OutFile << '5'; // default ist 5 fx_OutFile << endl; } return (true); }bei mir funktioniert das jetzt

.. und nun sag' uns bitte noch wie viel Zeit die Datei mit den 200000 Zeilen benötigt.Gruß
Werner
-
wow, super!
Ich hatte heute Anbend noch Zeit es zu testen und habe noch schnell einen Timer drumherum gebastelt. für 188301 Zeilen habe ich auf meinem Laptop 2:26:11 Stunden gebracht, Die Zeit hat sich also fast um die Hälfte verkürzt. Vielen Dank nochmal!
Jetzt muss ich die Vorlage nur noch ein paar mal umbasteln für die ganzen anderen Dateien, dann sollte das Programm komplett laufen.
Super Support, jungs!
-
campinge schrieb:
für 188301 Zeilen habe ich auf meinem Laptop 2:26:11 Stunden gebraucht
Im Release-Mode? O.o
bb
-
@Werner Salomon:

und jetzt, wo der code aufgeräumt ist,
mir scheint, man könnte fx_Compare nach dem einlesen sortieren und dann statt find lieber lower_bound nehmen. müßte den lauf eigentlich vom stundenbereich in den sekundenbereich drücken.ich hab fast nix geändert und es auch nicht getestet. so diese richtung meine ich:
#include <algorithm> // sort, find #include <iostream> #include <fstream> #include <string> #include <deque> // -- Helferlein zum Einlesen eines erwarteten Zeichens template< char C > std::istream& Char( std::istream& in ) { char c; if( in >> c && c != C ) in.setstate( std::ios_base::failbit ); return in; } struct Entry // Struktur für das Eingangsfile { bool operator<( const Entry& b ) const // legt die Reihenfolge bei 'sort' fest { return m_fix < b.m_fix; } std::string m_fix; // String für das Fix double m_latitude; // bool für Latitude double m_longitude; // bool für longlitude }; struct Compare // Strukur für das Vergleichsfile { explicit Compare( const std::string& fix = std::string() ) // Konstruktor für Vergleiche : m_fix( fix ) , m_latitude(), m_longitude() , m_Number() {} bool operator<( const Compare& b ) const // legt die Reihenfolge bei 'sort' fest { return m_fix < b.m_fix; } bool operator==( const Compare& b ) const { return m_fix == b.m_fix; } std::string m_fix; // String für das Fix double m_latitude; // bool für latitude double m_longitude; // bool für longlitude int m_Number; // int für die nummer }; bool operator!=( const Compare& a, const Compare& b ) { return !(a == b); } std::istream& operator>>( std::istream& in, Entry& e ) // Lesen { // lese 'fix', ab nächsten char 5 Zeichen ignorieren, lese 'latitude' und 'longitude' return (in >> e.m_fix >> std::ws).ignore( 5 ) >> e.m_latitude >> e.m_longitude; } std::ostream& operator<<( std::ostream& out, const Entry e ) // Formatieren { // Ausgabe im neuen Format // z.B.: ENTRE;-31.534170;130.949200 return out << e.m_fix << ';' << e.m_latitude << ';' << e.m_longitude; } std::istream& operator>>( std::istream& in, Compare& f ) // Lesen { // lese 'fix' bis';', 'latitude', ';', 'longitude', ';' und 'nummer' // z.B.: 00MKK;22.528056;-156.170961;3 return std::getline( in, f.m_fix, ';' ) >> f.m_latitude >> Char<';'> >> f.m_longitude >> Char<';'> >> f.m_Number; } std::istream& comment( std::istream& in ) // überliest Kommentar beginnend mit ';' { while( in >> std::ws && !in.eof() && char(in.peek()) == ';' ) in.ignore( 999, '\n' ); return in; } std::istream& comment2( std::istream& in ) // überliest Kommentar beginnend mit '/' { while( in >> std::ws && !in.eof() && char(in.peek()) == '/' ) in.ignore( 999, '\n' ); return in; } int ExportFixes() { using namespace std; deque< Entry > fx_Entries; // Container mit Struktur "Entry" erstellen { std::ifstream fx_fwpNavFIX("navdata/wpNavFIX.txt"); // Input- Datei wpNavFix definieren for(Entry e; fx_fwpNavFIX >> comment >> e; ) // Einträge von Entry durchlaufen { fx_Entries.push_back( e ); // e in fx_Entries einfügen } sort( fx_Entries.begin(), fx_Entries.end() ); // fx_Entries sortieren } deque< Compare > fx_Compare; { std::ifstream fx_fFixes("navigation/Fixes.db"); // Input-Datei Fixes definieren for( Compare f; fx_fFixes >> comment2 >> f; ) // Einträge von Entry durchlaufen { fx_Compare.push_back( f ); } //weg: nix weg, nur marker für neue zeile stable_sort( fx_Compare.begin(), fx_Compare.end() );//neu } ofstream fx_OutFile("navigation_new/Fixes.db"); // Ausgabedatei definieren for( deque< Entry >::iterator e = fx_Entries.begin(); e != fx_Entries.end(); ++e ) //fx_Entries durchlaufen { // -- alle Einträge aus 'navdata/wpNavFIX.txt' sortiert wegschreiben // hinter jeden Eintrag wird die Zahl geschrieben, die in 'navigation_new/Fixes.db' für diesen Eintrag // gefunden wurde. Falls keiner gefunden wurde, so wird eine '5' angehängt. fx_OutFile << *e << ';'; //weg deque< Compare >::iterator f = find( fx_Compare.begin(), fx_Compare.end(), Compare( e->m_fix ) ); deque< Compare >::iterator f = lower_bound( fx_Compare.begin(), fx_Compare.end(), Compare( e->m_fix ) );//neu //weg if( f != fx_Compare.end() ) if( f != fx_Compare.end() && f->m_fix==e->m_fix)//neu fx_OutFile << f->m_Number; // Nummer aus 'navigation_new/Fixes.db' für diesen Eintrag anhängen else fx_OutFile << '5'; // default ist 5 //weg fx_OutFile << endl; fx_OutFile << '\n';//neu, endl macht auch flush, nix gut } return (true); }
-

Ich hab gerade auf Release umgeschaltet und deinen veränderten code eingefügt.
Resultat : "Fixes Exported in: 0 Hours, 0 Minutes, 14 Seconds"
Genial, danke!!!!!!
Was macht lower_bound jetzt so anders, dass es SO viel schneller geht?
-
campinge schrieb:
Resultat : "Fixes Exported in: 0 Hours, 0 Minutes, 14 Seconds"
jup, das trifft meine erwartungen.
miss doch gerade noch, ob es einen merklichen effekt hat, wenn man beiden strukturen noch eine eigene swap-funktion spendiert. das würde glaub ich so gehen:
struct Entry // Struktur für das Eingangsfile { bool operator<( const Entry& b ) const // legt die Reihenfolge bei 'sort' fest { return m_fix < b.m_fix; } std::string m_fix; // String für das Fix double m_latitude; // bool für Latitude double m_longitude; // bool für longlitude friend template <typename T> std::swap(Entry& a,Entry& b) { std::swap(a.m_fix,b.m_fix); std::swap(a.m_latitude,b.m_latitude); std::swap(a.m_longitude,b.m_longitude); } }; struct Compare // Strukur für das Vergleichsfile { explicit Compare( const std::string& fix = std::string() ) // Konstruktor für Vergleiche : m_fix( fix ) , m_latitude(), m_longitude() , m_Number() {} bool operator<( const Compare& b ) const // legt die Reihenfolge bei 'sort' fest { return m_fix < b.m_fix; } bool operator==( const Compare& b ) const { return m_fix == b.m_fix; } std::string m_fix; // String für das Fix double m_latitude; // bool für latitude double m_longitude; // bool für longlitude int m_Number; // int für die nummer friend template <typename T> std::swap(Compare& a,Compare& b) { std::swap(a.m_fix,b.m_fix); std::swap(a.m_latitude,b.m_latitude); std::swap(a.m_longitude,b.m_longitude); std::swap(a.m_Number,b.m_Number); } };
-
hm, das bringt mir jetzt eine compiler-Fehlermeldung:
(10) error C2059: syntax error : 'template<'
(10) error C2899: typename cannot de used outside a template declaration
(12) error C2334: unexpected token(s) precending '{'; skipping appearant function bodyund das halt 2 mal...
-
ich habs auch verdreht.
template <typename T> friendsolls heißen.
sorry. und ich weiß nicht sicher, obs damit dann geht.
-
oha, das hat's sogar noch schlimmer gemacht:
nur mal ein kleiner Ausschnitt:
'std::swap' : not a function
'std::swap' : dependant name is not a type prefix with 'typename' to indicate a type
'swap' : cannot be a template definition
binary '==' 'const Compare' does not define this operator or a conversion to a type acceptable.....das geht so dann +100 Zeilen weiter o.O
(56 errors)
-
#include <algorithm>