Chars zusammenfügen und sortieren



  • Ich würde unbedingt noch ein wenig mit den Containern experimentieren. An den Datenstrukturen kannst du momentan wohl am meisten optimieren (bei den Streams machst du ja nichts Unnötiges wie zwei Mal dasselbe lesen oder so?). Und deine Algorithmen wie die Umformatierung können auch nicht mehr wirklich schneller gemacht werden?

    Vielleicht kannst du auch mal die Boost.Pointer Container ausprobieren, die verwalten Zeiger auf Objekte, womit vor allem beim Sortieren Zeit durch die wegfallenden Kopien gespart werden könnte...



  • campinge schrieb:

    ok, danke Jungs!

    Den Fehler habe ich gestern gefunden. Ich hatte die Definition + Deklaration global gealten. Dadurch gings ned.
    Jetzt hab ich das kurz über die Schleife gehängt und siehe da, es klappt.
    Allerdings wieder mit gewohnter langsamkeit. Habe gestern für 5881 Zeilen 5-10 Minuten gebraucht, da freue ich mich ja schon auf die 200000 😞

    noch ist mir unklar, was du machen willst.
    mir fällt kaum was ein, was für 5000 datansätze 5min brauchen könnte.

    wie werden die drei dateien zusammengemischt? soll er von den dre dateien, wenn ein schlüssel mehrfach kommt, einfach nur die erste zeile nehmen, die diesen schlüssel hatte?
    falls ja, biste mit std::sort/std::unique oder std::map wieder im rennen bei den deutlich unterminutern.



  • Also, seekg habe ich schon ausprobiert. Allerdings scheint das nichts zu bringen, bzw. ist das Ergebnis trotzdem dasselbe.
    Die Dauer der Anwendung kann ich mir nur dadurch erklären, dass die Datei jedes mal neu eingelesen wird, und komplett durchgegengen werden muss.
    Den großen Block habe ich heute mal getestet, Pro Sekunde eine Linie x 200000 ist viiel zu viel -.-

    Hier einfach mal der komplette quellcode:
    Ich hoffe das macht das optimieren etwas einfacher...

    // Export the fixes for the FMC
    //
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <deque>
    #include <set>
    #include <algorithm>
    #include "windows.h"
    
    using namespace std;
    
    //variables
    //
    int fx_err, fx_i, fx_x, fx_y, fx_zerocounter, fx_checksum;		// some counters int's
    int fx_linecounter = 1;											// a linecounter to print how much lines were edited
    
    char fx_chNumber[1], fx_chFix[5], fx_chLatitude[10];			// String for Number, Fix, Latitude
    char fx_chString2[100], fx_chLonglitude[11], fx_chTemp[5];		// temp string, Longlitude String, temp string
    char fx_chString[100], fx_chDataString[100];					// 2 strings for the Data
    
    bool fx_Result;													// bool for the Result or the function
    
    FILE *fx_fwpNavFIX;												// FILE where the fixes are taken from
    FILE *fx_fFixes;												// FILE where the numbers are taken from
    FILE *fx_fNewFixes;												// FILE where evereything will be saved in
    
    fpos_t fx_pos, fx_pos2;											// Storage for the Position counters in the files
    std::deque<std::string> fx_Entries;								// List where the data will be sorted in
    std::string fx_Line, fx_Line2;									// 2 strings for pre-saving the lines
    
    // Prototypes
    //
    int fx_checkline(char fx_chLine[100], char fx_chCheckFix[5], int *fx_checksum);
    
    //
    // Functions
    //
    int ExportFixes ()
    {
    	// open the Level-D wpNavFIX file
    	//
    	if(fx_err = fopen_s( &fx_fwpNavFIX, "navdata/wpNavFix.txt", "r") != 0)
    	{	MessageBox(NULL, "Error opening navdata/wpNavFix.txt \nPlease make sure it exists!", "Error!", 0); return false;	}
    
    	// open the old Fixes.db since there are a few things needed
    	//
    	if(fx_err = fopen_s( &fx_fFixes, "navigation/Fixes.db", "r") != 0)
    	{	MessageBox(NULL, "Error opening navigation/Fixes.db \nPlease make sure it exists", "Error!", 0); return false;	}
    
    	// create the CD Fixes.db file. If existing, delete content
    	//
    	if(fx_err = fopen_s( &fx_fNewFixes, "navigation_new/Fixes.db", "w") != 0)
    	{	MessageBox(NULL, "Error creating navigation_new/Fixes.db \nAre you logged on as Administrator?", "Error!", 0); return false;	}
    
    	// write the header in the file
    	//
    	fputs ("//Aeronautical Data Exported from official AIRAC by www.navigraph.com.\n", fx_fNewFixes);
    	fputs ("//All rights reserved. Exporting is only legal if you bought the navdata there.\n", fx_fNewFixes);
    	fputs ("//Sharing is Illegal! Files Exported with LVD2CS.exe, freeware, copyright by me.\n", fx_fNewFixes);
    	fputs ("//---------------------------------------------------------------------------\n", fx_fNewFixes);
    	fputs ("//Aeronautical data for Captain Sim flight simulation products.\n", fx_fNewFixes);
    	fputs ("//DO NOT USE FOR FLIGHT PLANNING OR IN-FLIGHT NAVIGATION!\n", fx_fNewFixes);
    	fputs ("//(c)1999-2007 Captain Sim www.captainsim.com\n", fx_fNewFixes);
    	fputs ("//Effective dates: 14 FEB 2008 - 12 MAR 2008\n", fx_fNewFixes);
    	fputs ("//---------------------------------------------------------------------------\n", fx_fNewFixes);
    	fclose (fx_fNewFixes);
    
    	cout << endl << "Converting Fixes..." << endl; 
    	do
    	{
    		// copy a line from the Level-D navdata
    		fgets (fx_chString, 99, fx_fwpNavFIX);
    
    		// Set Start conditions
    		//
    		fx_Result = false;
    		fx_checksum = false;
    
    		// now, cut the line in different parts and safe them in their strings
    		//
    		if (fx_chString[0] != ';')
    		{
    			// cut for the Fix
    			//
    			fx_y = 0;
    			fx_zerocounter = 1;
    			for (fx_x=0; fx_x<5; fx_x++)
    			{
    				if (fx_chString[fx_x] != ' ')
    				{
    					fx_chFix[fx_y] = fx_chString[fx_x];
    					fx_y++;
    				}
    				else // if there was found a space, set the last part of the char to false
    				{
    					fx_chFix[sizeof(fx_chFix)-fx_zerocounter] = false;
    					fx_zerocounter++;
    				}
    
    			}
    			// cut for the Latitude
    			//
    			fx_y = 0;
    			fx_zerocounter = 1;
    			for (fx_x=29; fx_x<39; fx_x++)
    			{
    				if (fx_chString[fx_x] != ' ')
    				{
    					fx_chLatitude[fx_y] = fx_chString[fx_x];
    					fx_y++;
    				}
    				else // if there was found a space, set the last part of the char to false
    				{
    					fx_chLatitude[sizeof(fx_chLatitude)-fx_zerocounter] = false;
    					fx_zerocounter++;
    				}
    			}
    			// cut for the longlitude
    			//
    			fx_y = 0;
    			fx_zerocounter = 1;
    			for (fx_x=39; fx_x<50; fx_x++)
    			{
    				if (fx_chString[fx_x] != ' ')	
    				{
    					fx_chLonglitude[fx_y] = fx_chString[fx_x];
    					fx_y++;
    				}
    				else // if there was found a space, set the last part of the char to false
    				{
    					fx_chLonglitude[sizeof(fx_chLonglitude)-fx_zerocounter] = '\0';
    					fx_zerocounter++;
    				}
    			}
    
    			// copy the old Fixes.db to a container and create a list. then copy the string to
    			// the char chString2 to send it to the function fx_checkline(). this returns true or false
    			//
    
    			std::ifstream fx_InFile1 ("navigation/Fixes.db");
    
    				//******************************
    				//achtung:
    				// hier oben ist der Grund dafür, warum alles so langsam geht. Bei jedem Durchlauf der Hauptschleife
    				// wird das ~2mb-File neu eingeladen. Wenn ich das allerdings global mache, bekomme ich nach dem 
    				// ersten Durchlauf der Hauptschleife in der unteren nurnoch müll raus...
    				//******************************
    
    			//fx_InFile1.seekg (0, ios::beg);	// this is not working?
    			std::set<std::string> fx_List1;
    
    			while (std::getline(fx_InFile1, fx_Line2) && fx_checksum != true && fx_Result != true)
    			{
    
    				strcpy_s(fx_chString2, fx_Line2.c_str());
    				strcpy(fx_chTemp, fx_chFix);
    				fx_Result = fx_checkline(fx_chString2, fx_chTemp, &fx_checksum);
    			}
    
    			// if checksum is true, the end of the searchfile was reached and the fix is not
    			// in the old Airports.dat. Set the Number to '5', or print for manual addition
    			//
    			if (fx_checksum == true)
    			{
    				cout << fx_chFix << endl;
    				fx_chNumber[0] = '5';
    				cout << fx_chFix << endl;
    
    				//********************************
    				// achtung:
    				// Die Zeile hier oben soll, wenn kein passender eintrag in der Funktion checkfix
    				// gefunden wurde, chNumber auf '5' setzen. Allerdings, setzt das auch gleichzeitig 
    				// fx_chFix[5] auf '5'. Warum ist mir nicht klar. Wenn ich dann chNumber[5] auf 
    				// false setze, wird chNumber auch zu false....
    				//*************************************
    				fx_chFix[5] = false;	
    			}
    
    			// if the fix was found, copy the last letter from the chString2
    			// and paste it in chNumber
    			//
    			else
    			{
    				fx_chNumber[0] = fx_chString2[strlen(fx_chString2)-1];
    			}
    
    			//Print some Information on the screen to make visible that the progress is still working
    			//
    			if (fx_linecounter == 1000)
    				cout << "  " << fx_linecounter << " fixes exported...still working" << endl;
    			if (fx_linecounter == 5000)
    				cout << "  " << fx_linecounter << " fixes exported...still working" << endl;
    			if (fx_linecounter == 10000)
    				cout << " " << fx_linecounter << " fixes exported...still working" << endl;
    			if (fx_linecounter == 25000)
    				cout << " " << fx_linecounter << " fixes exported...still working" << endl;
    			if (fx_linecounter == 50000)
    				cout << " " << fx_linecounter << " fixes exported...still working" << endl;
    			if (fx_linecounter == 100000)
    				cout << fx_linecounter << " fixes exported...still working" << endl;
    			if (fx_linecounter == 150000)
    				cout << fx_linecounter << " fixes exported...still working" << endl;
    			if (fx_linecounter == 200000)
    				cout << fx_linecounter << " fixes exported...still working" << endl;
    			if (fx_linecounter == 250000)
    				cout << fx_linecounter << " fixes exported...still working" << endl;
    			if (fx_linecounter == 300000)
    				cout << fx_linecounter << " fixes exported...still working" << endl;
    
    			//copy all informations in one single string
    			//
    			strcpy_s(fx_chDataString, fx_chFix);
    			strcat_s(fx_chDataString, ";");
    			strcat_s(fx_chDataString, fx_chLatitude);
    			strcat_s(fx_chDataString, ";");
    			strcat_s(fx_chDataString, fx_chLonglitude);
    			strcat_s(fx_chDataString, ";");
    			strcat_s(fx_chDataString, fx_chNumber);
    			strcat_s(fx_chDataString, "\n");
    			cout << fx_chDataString;
    
    			//And push that one into a container 
    			//
    			fx_Entries.push_back(fx_chDataString);
    
    			//count the fixes exported
    			fx_linecounter++; 
    		} 
    	} while ((fx_chFix[0] != '0' || fx_chFix[1] != '0' || fx_chFix[2] != '0' || fx_chFix[3] != '0' || fx_chFix[4] != '0') && (fx_chFix[0] != 'N' || fx_chFix[1] != 'P' || fx_chFix[2] != 'O' || fx_chFix[3] != 'L' || fx_chFix[4] != 'E') );
    	// quit the circle when the last waypoint "NPOLE" is reached...
    	cout << "Successfully edited " << fx_linecounter << " fixes!" << endl;
    
    	// Sort the container
    	//
    	cout << "Sorting container..." << endl;
    	std::sort(fx_Entries.begin(), fx_Entries.end());
    
    	// and write the container in the file
    	//
    	cout << "Writing..." << endl;
    	std::ofstream fx_OutFile ("navigation_new/Fixes.db", std::ios_base::out | std::ios_base::app);
    
    	for (std::deque<std::string>::iterator fx_a = fx_Entries.begin(); fx_a != fx_Entries.end(); ++fx_a)
    	{
    		fx_OutFile << (*fx_a);		// write line in file
    	}
    
    	fx_OutFile.close();
    	cout << "Successfully finished exporting Fixes" << endl;
    
    	return (true);
    }
    
    // function checkline
    //
    // this function checks, if the Fix halded over is inside the String
    // if it is, the function returns true.
    //
    
    //********************
    // achtung:
    // diese Funktion funktioniert zwa, ist aber glaub ich nicht wirklich effektiv. 
    // mir sind hier leider dieIdeeen ausgegangen, gibt's da ne möglichkeit das 
    // kleiner und effektiver zu bekommen?
    //***********************
    
    int fx_checkline(char fx_chLine[100], char fx_chCheckFix[5], int *fx_checksum)
    {
    	if (fx_chLine[0] == '/')
    	{
    		return (false);
    	}
    	else if (fx_chLine[0] == 'Z' && fx_chLine[1] == 'Z' && fx_chLine[2] == 'V' && fx_chLine[3] == '6' && fx_chLine[4] == '5')
    	{
    		*fx_checksum = true;
    		return (false);
    	}
    	else if (fx_chLine[0] == fx_chCheckFix[0] && fx_chLine[1] == fx_chCheckFix[1])
    	{
    		if(fx_chCheckFix[2] == false && fx_chCheckFix[3] == false && fx_chCheckFix[4] == false && fx_chLine[2] == ';')
    		{
    			return (true);
    		}
    		else if (fx_chLine[2] == fx_chCheckFix[2])
    		{
    			if (fx_chCheckFix[3] == false && fx_chCheckFix[4] == false && fx_chLine[3] == ';')
    			{
    				return (true);
    			}
    			else if (fx_chCheckFix[3] == fx_chLine[3])
    			{
    				if (fx_chCheckFix[4] == false && fx_chLine[4] == ';')
    				{
    					return (true);
    				}
    				else if (fx_chCheckFix[4] == fx_chLine[4])
    				{
    					return (true);
    				}
    				else
    				{
    					*fx_checksum = false;
    					return (false);
    				}
    			}
    			else
    			{
    				*fx_checksum = false;
    				return (false);
    			}
    		}
    		else
    		{
    			*fx_checksum = false;
    			return (false);
    		}		 
    	}
    	else
    	{
    		*fx_checksum = false;
    		return (false);
    	}
    }
    


  • campinge schrieb:

    Die Dauer der Anwendung kann ich mir nur dadurch erklären, dass die Datei jedes mal neu eingelesen wird, und komplett durchgegengen werden muss.

    Warum liest du sie dann mehrfach ein? Streams und vor allem Festplattenzugriffe sind langsam. Also nimm die Werte einmal in den Arbeitsspeicher und arbeite dort weiter...

    Ich hab deinen Code nicht genau angeschaut, aber mir fällt auf, dass du sehr viele C-Mittel verwendest. Sind dir die C++-Alternativen noch zu wenig bekannt (vor allem std::fstream und std::string )? Denn diese können dir das Leben erleichtern. Und sie sind bestimmt nicht der Grund für die Langsamkeit.



  • 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 mit good() , ob alles in Ordnung ist. Mit clear() 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_Fix
    

    oder:

    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;3
    

    Programm:

    #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.000000
    

    ist 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;1
    

    also 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);
        }
    };
    

Anmelden zum Antworten