.ini Datei einlesen, Defaults erkennen.



  • Hallo.
    Ich habe folgende Aufgabe:
    Es soll eine .ini Datei eingelesen werden und alle Werte/Values entfernt werden. So das ich quasi anschließend ne blanke .ini Datei habe wo nur die Sektions und Schlüssel stehen.
    ABER bei bestimmten Schlüssel soll er Standardwerte erkennen und bei dem Schlüssel dann den Standardwert eintragen bzw. nicht löschen.

    [Sektion}
    Schlüssel1=lalala
    #Standardwert:500
    Schlüssel2=450
    Schlüsel3=abc78

    Nach dem ich mein Programm ausgeführt wurde, soll die.ini so aussehen:

    [Sektion}
    Schlüssel1=
    #Standardwert:500
    Schlüssel2=500
    Schlüsel3=

    Also das er mir alle Werte löscht, hab ich hinbekommen.
    Nun muss ich sehen, dass er die Defaults erkennt.
    Ich bin damit angefangen, mir eine Funktion zu basteln, die die .ini Datei als String einliest und die Defaulst anhand von "#Standardwert:" erkennt.

    while (! f.eof()) 
    	{
    		getline(f, sInhalt);
    		string::size_type sDefaults = sInhalt.find( "#Standard:", 0 );
    
    		if( sDefaults != string::npos ) 
    			{
    				string sAusgabe = sInhalt.substr(10);
    				cout << "Default gefunden: " <<sAusgabe<< endl;								
    			}	
    	}
    

    So die Defaults fischt er mir raus. Aber wir verklicker ich dem jetzt, dass diese Defaultwert zu der Zeile die als näcähstes eingelesen wird gehört. Sprich

    "#Standardwert:500" wird gefunden. Der Wert gehört zur nächsten Zeile die eingelesen wird. (Also zum Schlüssel2)

    Wisst ihr was ich meine?


  • Mod

    Ich verstehe wohl, was du meinst, das ganze ist aber eng verknüpft mit den Details deiner Ein-/Ausgabe der sonstigen Zeilen. Für kon krete Hinweise müsstest du die hier auch noch posten.

    Wenn ich das Problem lösen wollte, würde ich das so machen (Pseudocode):

    istream eingabe;
    ostream ausgabe;
    string inhalt;
    
    {while getline(eingabe, inhalt, '=')){   // Alles bis zum nächsten gleich einlesen
     string default;
     size_type anfang= inhalt.find( "#Standard:");  // Gucken ob #Standard drin ist
         if( anfang!= string::npos )
                {
                 size_type ende= inhalt.find( "\n",anfang);
                 default = inhalt.substr(anfang+10,ende-anfang-10); // Alles zwischen Doppelpunkt und nächster Zeile ist Defaultwert
                 cout << "Default gefunden: " <<default<< endl;                               
                }
         ausgabe << inhalt << '=' << default << endl;  // Alles bis zum '=' ausgeben, gegebenenfalls default anhängen
         eingabe.ignore(max_int,'\n');  // Rest der Zeile verwerfen
        }
    


  • Hey Danke für deine Antwort.
    Also ich habe mal ein "manuellen" Defaultwert eingebaut in meinem Programm:

    //Schleife: Alle Entry der Section editieren
    			for (nlen2=0, strtok2=_T("x"); !strtok2.IsEmpty(); nlen2=nlen2+strtok2.GetLength()+1)
    
    				{
    				strtok2=&szT2[nlen2];
    				if (strtok2.IsEmpty())
    					break;
    
    				if (strtok2!="KEY") //Test: Beim Entry KEY.....
    					BOOL bRes = ::WritePrivateProfileString(strtok, strtok2,_T(""), argv[1]); //Entry editieren		
    				else
    					BOOL bRes = ::WritePrivateProfileString(strtok, strtok2,_T("500"), argv[1]); //Test: ... wird als Defaultwert 500 eingetragen
    				}
    

    Er geht nun jede Sektion durch und editiert nun jeden Schlüsselwer in " " (also nichts) um.

    Wenn nun der Schlüssel (mein manueller Test) z.B. "KEY" heißt, editiert er den Defaultwert "500"rein.

    Nun muss ich das halt irgendwie automatisieren, dass er automatisch erkennt das übern Schlüssel ein Kommentar mit #Standard:x ist und er auch weiß, dass es ein Defaultwert ist und entsprechend editiert.

    Ich weiß noch nciht mal wie ich überhaupt prüfen soll, ob da über nen Kommentar# steht?!

    Er liest ja irgendwie nur Sektion oder Entries



  • Das wirst du mit der WinAPI-Funktion WritePrivateProfileString() nicht hinbekommen. Du mußt schon selber die Ini-Datei (Zeile für Zeile) parsen und wieder zurückschreiben (SeppJ hat es ja schon ansatzweise gezeigt, du mußt halt einfach jede Zeile einzeln mit getline() lesen und dann entsprechend auf Kommentarzeichen '#' oder Eintrag ('=') überprüfen).



  • Th69 schrieb:

    Das wirst du mit der WinAPI-Funktion WritePrivateProfileString() nicht hinbekommen. Du mußt schon selber die Ini-Datei (Zeile für Zeile) parsen und wieder zurückschreiben (SeppJ hat es ja schon ansatzweise gezeigt, du mußt halt einfach jede Zeile einzeln mit getline() lesen und dann entsprechend auf Kommentarzeichen '#' oder Eintrag ('=') überprüfen).

    Ja ich muss das ja aber irgendwie nachher auf WritePrivateProfileString übertragen.
    Weils damit ja editiert wird



  • Klar kannst du es so machen, daß du erst den Defaultwert ausliest, dann die nächste Zeile parst und dann mittels WritePrivateProfileString() den Wert zurückschreibst.

    Dies erscheint mir aber unnötig und fehleranfälliger.
    Du hast ja quasi ein eigenes Ini-Format geschaffen, da du ja aus den Kommentaren dir die Defaultwerte heraussuchst.

    Somit kannst du doch einfach selber die Ini-Datei erzeugen.
    Du willst ja explizit alle Werte zurücksetzen und dann benutze einfach einen fstream, der nach dem Lesen dann die (evtl. geänderte Zeile) wieder zurückschreibt.

    P.S. Du mußt beim Parser natürlich noch zusätzlich auf Sections [...] und Leerzeilen prüfen.


Anmelden zum Antworten