Ini Script?



  • naja, string war mit bissche stressig beim laden.

    string str;
    file >> str ist ja leider nicht möglich.
    --> ich wuuste nciht, wie ich das mit den STL string rutinen löse



  • PS: Ich hätte die Suche nach der richtigen Sektion und Schlüssel vermutlich anders gelöst, aber egal 😉

    Das würde mich mal interessieren!! Vllt. gibs es ja noch viel bessere Wege, aber auf die map Geschichte möchste ich verzichten.

    mfg



  • Hallo,

    zuerst würde ich die komplette ini-Datei einlesen und in einer Map speichern
    mit der Section als Key vom Typ std::string und Value eine Struktur mit
    den Variablen name und wert vom Typ std::string.

    pseudo-code:

    struct SecVal
    {
    std::string name;
    std::string value;
    }

    typedef std::map< std::string, std::vector<SecVal>, std::less< std::string > > MapIniFile;

    Dann ein Funktion schreiben, die die nächste Section sucht, den Wert zurückgibt, und dabei alle Leerzeilen und Kommentarzeilen überliest.

    Die nächste Funktion ließt so lange die Tokens name = Wert bis die auf eine
    Section trifft oder auf's Dateiende. In der Funktion erzeugst Du für jeden
    Eintrag ein Objekt vom Typ SecVal und füllst name und Wert und hängst die
    mit push_back in den Vector. Die Funktion nimmt eine Referenz von dem Vektor
    und gibt den damit zurück.

    // Trennzeichen mit übergeben, damit die Funktion auch mal nach anderen
    // Trennzeichen suchen kann.

    void readToken( std::vector< SecVal >& vecSecVal, char delim = '=' )

    pseudo-code:
    void readIniFile( fsteam& f, MapIniFile& mapIniFile, ...)
    {
    std::string sSection = findSection( fstream& f );
    std::vector< SecVal > vecSecVal;
    readToken( fstream& f, std::vector< SecVal >& vecSecVal );

    mapIniFile.insert( MapIniFile::value_type( sSection, vecSecVal );
    }

    In deinem Programm kannst Du dann mit

    MapIniFile::const_iterator iter = mapIniFile.find( "SectionName" );

    die Section finden.

    Mit
    const std::string& sSec = (*iter).first;
    const std::vector< SecVal >& vecSecVal = (*iter).second;
    kannst Du auf die Werte zugreifen.

    Innerhalb des Vectors mußt Du dann nach dem Namen suchen, um den Wert zu
    erhalten, oder Du packst das auch noch mal in eine map.

    Ich hoffe, ich habe in der Eile keinen Mist geschrieben,
    ich muss jetzt leider weg.



  • Ja, das map Prinzip kenne ich, ich möchte aber unbedingt nach meinem weg arbeiten, da das Map verfahren für mich ungeeignet ist!

    aber vielen Dank.

    Ich habe da mal eine Frage:

    height=480
    

    --> wie kann ich hier am betsen alles vor dem '='löschen?, sodass ich nur noch 480 habe? natürlich sollte ich vorher noch Leerzeichen entfernen.
    Die Funktion funktioniert jetzt auch soweit, muss nur unbedingt optimiert werden.

    string parse_string(const string& section, const string& key)
    {
    	std::fstream file("test.ini", std::ios::in | std::ios::binary);
    	char buffer[254];
    
    	// solange machen, bis Dateiende erreicht
    	while(!file.eof())
    	{
    		// Zeile für Zeile holen
    		file.getline(buffer, 254, '\n');
    
    		// Zeile enthält den Tag der gewünschten Sektion?
    		if(strstr(buffer, section.c_str()) != 0)
    		{
    			//gut, Sektion gefunden
    			file.getline(buffer, 254, '\n');
    
    			// schleife, um Sektion nach Key zu durchsuchen
    			while(1)
    			{
    				// nur solange, solange keine neue Sektion beginnt bzw. Datei zuende ist
    				file.getline(buffer, 254, '\n');
    				if(buffer[0] == '[' || file.eof())
    					break;
    
    				// gucken, ob wie key finden
    				if(strstr(buffer, key.c_str()) != 0)
    				{
    					// ja!!!! okay, leerzeichen entfernen und alles, was nach dem '=' steht zurückgeben
    					cout << buffer << "\n";
    
    				}
    
    			}
    
    		}
    	}
    
    	return 0;
    }
    


  • fletschen schrieb:

    ...ich möchte aber unbedingt nach meinem weg arbeiten, da das Map verfahren für mich ungeeignet ist!...

    Das musst Du mir erklären !

    Ich kann mir ja vorstellen, dass jemand lieber mit "Pointerschieberei" rumfrickelt (z.B. weil er das gewohnt ist) ... aber dass "das Map-Verfahren ungeeignet ist", leuchtet mir nicht ein.

    Auch, was an string "stressig" sein soll (außer, dass man die ganze Speicher(größen)verwalterei nicht mehr braucht), ist mir bislang nicht aufgefallen.

    Gruß,

    Simon2.



  • Ne map ist ungeeignet, weil die Sortiert.
    Wenn man dann die Ini ausliest und zurück schreibt sind die Einträge in einer anderen Reihenfolge als diese geschrieben wurden.

    Rein technisch macht das keinen Unterschied, aber wenn erst die Kommentare zu den Einträgen kommen und dann die Einträge selbst....

    Zumal die Reihenfolge wichtig sein kann für die Wartung einer Software.

    Mit einer list im zusammenhang mit pair lässt sich das Problem aber sehr ellegant lösen 🤡



  • Auch, was an string "stressig" sein soll (außer, dass man die ganze Speicher(größen)verwalterei nicht mehr braucht), ist mir bislang nicht aufgefallen.

    Hi
    Simon, dann lese bitte, was ich schreibe:

    1. Die Funktions ist ein Teil von was größerem
    2. Ich wusste nicht, wie ich am besten einen enen std::string mit dem inhalt der datei fülle, denn file >> string geht ja nicht...
    3. WIll ich alles noch optimieren --> Geschwindigkeit, Schleifen udn alles durch strings udn Stringroutinen ersetzten.

    mfg



  • Knuddlbaer schrieb:

    Ne map ist ungeeignet, weil die Sortiert....

    Das sehe ich ein.
    Aber dafür gibt es ja (wie von Dir schon gesagt) andere Standardmöglichkeiten ...

    Das mit dem String sehe ich immer noch nicht ein - ich vermute, dass bei fletschen tatsächlich ein Mangel an Erfahrung mit den STL-Möglichkeiten die Motivation für seine Abneigung ist. Weder Programmgröße noch spätere Optimierungsmöglichkeiten sprechen prinzipiell gegen string, zumal:
    - Gerade die Verwendung von string Programme in den allermeisten Fällen kürzer und wartbarer macht,
    - die Propertyanalyse prima zu trennen ist vom Rest des Programms (kann man sogar eine eigene Lib draus machen, die man unabhängig von der Programmgröße einsetzen kann) und
    - Optimierungen üblicherweise erst sehr weit hinten in der Entwicklungsphase sinnvoll sind (nach gründlicher Analyse) und oftmals nur sehr vereinzelte Funktionalitäten betrifft.

    Mein Tipp deswegen an fretschen:
    Lies Dich lieber 2 Tage in die STL ein und schreibe Dein Programm in 2 weiteren als noch 2 Wochen mit Rumfrickeln und Fehlersuche zu verbringen. 😉

    Gruß,

    Simon2.



  • Da stimme ich Simon2 zu, die STL hat mir bei meiner eigenen ini Lib sehr geholfen. (Zumal man auf viele Spielereien kommt. Die Komination aus string stream und templates lassen da viel Freiraum für individualisierung 🤡



  • Klar eine Map sortiert, kommt aber immer drauf an, was man haben will.
    Ich könnte aber bei der man für den Key ebenfalls eine Struktur definieren,
    die so aussieht,

    struct
    {
    int num;
    std::string sSection;
    }

    und dann nach dem Typ int sortieren lassen über einen operator, wobei
    die Sectionnummerierung der Reihenfolge nach erfolgt. Schon bleibt die
    IniDatei so wie sie war.

    Oder man nimmt ein Pair.

    Egal.

    Sollte nur ein Vorschlag sein.

    Das Aufspalten nach dem = Zeichen name und Wert, kann man
    a) mit den std::string Methoden machen, Stichwort find_first_of
    b) C-Funktion strtok
    c) istream_iterator, wie das geht steht auch schon im Forum
    d) man rennt in einer Schleife über den String und sucht selber nach dem = Zeichen
    e) die C-Funktion strstr liefert auch einen Pointer auf das Zeichen zurück.

    Wenn man das Zeichen gefunden hat, dann alle Blanks überlesen und den Rest merken.

    Viel Spaß noch



  • fletschen schrieb:

    1. Die Funktions ist ein Teil von was größerem

    Ein Grund mehr, sich nicht mit der Verwaltung von char-Pointern rumärgern zu müssen

    2. Ich wusste nicht, wie ich am besten einen enen std::string mit dem inhalt der datei fülle, denn file >> string geht ja nicht...

    versuch's mal mit getline() (das gibt's auch als globale Funktion zum Einlesen von std::string's)

    3. WIll ich alles noch optimieren --> Geschwindigkeit, Schleifen udn alles durch strings udn Stringroutinen ersetzten.

    Na dann fang gleich damit an 😉



  • Ts, dieses Thread zeigt mir, wie verwöhnt ich bin ... ich hätte doch glatt Spirit für die Aufgabe verwendet.


Anmelden zum Antworten