ProfilString



  • Wie meinst du das, Defaults erkennen? Meinst du, dass in der ini der Eintrag gar nicht enthalten ist und somit der Defaultwert genommen wird, und das du das erkennen willst? Dann kannst du, soweit mir bekannt, nur versuchen, als Default einen 'ungültigen' Wert zu nehmen, der garantiert nicht in der Datei vorkommen kann. Im Anschluss kannst du das dann abfragen.



  • Martin Richter schrieb:

    Übergib als default einen Wert, der nicht in der Datei stehen kann, und prüfe ob dieser zurückgegeben wird.

    Wie meinst du das, einen Wert der nicht in der Datei stehen kann?



  • Claudiah schrieb:

    Martin Richter schrieb:

    Übergib als default einen Wert, der nicht in der Datei stehen kann, und prüfe ob dieser zurückgegeben wird.

    Wie meinst du das, einen Wert der nicht in der Datei stehen kann?

    Wenn du einen Key hast, in dem normalerweise Werte von z.B. 0-1000 stehen können, dann nimmst du als Defaultwert für GetPrivateProfileString einfach "-1" und kannst im Anschluss abfragen, ob "-1" zugewiesen wurde. Ist das der Fall, kannst du relativ sicher sein, dass kein Eintrag gefunden und der Defaultwert verwendet wurde.



  • Ich meinte das so:

    [DB_CONNECTION]
    ;Default: Admin
    USER=Testacc
    PASS=12345
    ;Default: Datenbank-Xray
    DB=Testdatenbank

    Nach dem das Programm ausgeführt wurde, soll es so aussehen:

    [DB_CONNECTION]
    ;Default: Admin
    USER=Admin
    PASS=12345
    ;Default: Datenbank-Xray
    DB=Datenbank-Xray



  • Sind Semikola in ini's nicht Kommentare?

    Also wenn du willst, dass dein Defaultwert da eingetragen wird, tja, also ich würde das Semikolon wegnehmen und stattdessen 'DefaultAdmin' oder so schreiben. Dann kannst du ja den Defaultwert einlesen und bei Bedarf im Key Admin setzen. Aber einen Automatismus, wie du ihn scheinbar haben willst (dass er automatisch das ';Default' über einem Key erkennt), wirst du bestimmt nicht finden.



  • _matze schrieb:

    Sind Semikola in ini's nicht Kommentare?

    Also wenn du willst, dass dein Defaultwert da eingetragen wird, tja, also ich würde das Semikolon wegnehmen und stattdessen 'DefaultAdmin' oder so schreiben. Dann kannst du ja den Defaultwert einlesen und bei Bedarf im Key Admin setzen. Aber einen Automatismus, wie du ihn scheinbar haben willst (dass er automatisch das ';Default' über einem Key erkennt), wirst du bestimmt nicht finden.

    Hmm ok, ich überlege mir was.

    Aber nochmal ne andere Frage:

    Wie kann ich eine gefundene Sektion bearbeiten?
    mit
    BOOL bRes = ::WritePrivateProfileString(strtok, strtok2,_T(""), sParameter2);
    editiere ich ja den Wert.
    Wenn ich nun aber
    BOOL bRes = ::WritePrivateProfileString(strtok, "andererentryname",_T(""), sParameter2);
    schreibe, ersetzt er nicht den aktuellen eingelesen schlüssel sondern fügt einfach unten hinzu.



  • Du gibst mit dem 2. Parameter ja auch den Schlüssel an, der geschrieben werden soll. Wenn du da einen anderen 'reinschreibst, dann wird auch ein anderer Schlüssel geschrieben (und neu erzeugt, wenn noch nicht vorhanden). Behalte den 2. Parameter bei und ändere lieber den 3., dann klappt's.

    Btw, warum nimmst du eigentlich 'strtok' als Bezeichner? Halte ich für extrem ungünstig, schließlich gibt es eine CRT-Funktion, die so heißt.



  • _matze schrieb:

    Du gibst mit dem 2. Parameter ja auch den Schlüssel an, der geschrieben werden soll. Wenn du da einen anderen 'reinschreibst, dann wird auch ein anderer Schlüssel geschrieben (und neu erzeugt, wenn noch nicht vorhanden). Behalte den 2. Parameter bei und ändere lieber den 3., dann klappt's.

    Btw, warum nimmst du eigentlich 'strtok' als Bezeichner? Halte ich für extrem ungünstig, schließlich gibt es eine CRT-Funktion, die so heißt.

    Erstmal danke für deine Antwort.

    Aber wenn ich den dritten Parameter ändere, ändere ich ja nur den zugewiesenen Wert und nicht den Schlüssel.
    [Sektion ABC]
    User = Peter
    (schlüssel) (wert)

    Ich will den Schlüssel editieren.
    Also aus User beispielsweise "Name" machen.



  • Claudiah schrieb:

    Ich will den Schlüssel editieren.
    Also aus User beispielsweise "Name" machen.

    Tja, dafür ist die Funktion einfach nicht ausgelegt. Woher sollte sie denn beim zweiten Aufruf wissen, auf welchen Schlüssel du dich beziehst? Für die Funktion ist der übergebene String einfach ein Schlüssel, der noch nicht existiert und somit angelegt werden muss. Eine Beziehung zu einem anderen Schlüssel besteht bei diesem Aufruf nicht.

    Ich verstehe auch nicht ganz, warum man das machen wollen sollte. Vielleicht kannst du mir deine Beweggründe ja mal näher erläutern.

    EDIT: Mir ist auch keine Funktion bekannt, die einen Schlüssel löschen könnte (oder gibt's das?). Was du machen könntest, wäre eine ganze Sektion zu löschen, aber für dein Vorhaben müsstest du dann jeden Schlüssel unter einer eigenen Sektion speichern. Dann verlassen wir langsam den Pfad der korrekten Nutzung von Ini-Dateien... 😉



  • Ziel:
    Alle Werte löschen, außer die Defaults. Die sollen bleiben ggf. reingeschrieben werden.

    Kann man nicht irgendwie so eine "Automatik" programmieren, dass das Programm alle Werte löscht aber vor jedem löschen halt prüft

    Ist über dem Schlüssel ein Kommentar "#Default:123"?
    Wenn ja, editiere "123" als Wert

    BOOL bRes = ::WritePrivateProfileString(strtok, strtok2,_T("123"), sParameter2);
    

    Ansonsten "leeren"

    BOOL bRes = ::WritePrivateProfileString(strtok, strtok2,_T(""), sParameter2);
    

    Halt irgendwie prüfen, ob über dem Schlüssel ein Kommentar ;Defautl vorhanden ist



  • Nö, da müsstest du schon selbst einen Parser schreiben...



  • _matze schrieb:

    Nö, da müsstest du schon selbst einen Parser schreiben...

    Was ist Parser ? 🙄



  • Claudiah schrieb:

    _matze schrieb:

    Nö, da müsstest du schon selbst einen Parser schreiben...

    Was ist Parser ? 🙄

    Das heißt, du verzichtest auf Komfort-Funktionen wie GetPrivateProfileString und liest die Datei komplett selbst (z.B. mit ReadFile, fread, std::fstream...). Du liest Zeichen für Zeichen ein, stellst fest, wann ein Bezeichner für eine Sektion oder einen Schlüssel beginnt oder endet, wo der Wert steht usw. Wenn du das alles selbst machst, hast du natürlich auch alle Freiheiten und kannst deine Defaultwerte implementieren, wie du es willst.

    Aber ehrlich gesagt würde ich dir davon abraten (viel zu viel Aufwand) und lieber von der gewünschten Vorgehensweise absehen (bzw. diese zum Machbaren hin abändern).

    Was hältst du davon:

    - Wenn es einen Defaultwert für einen Schlüssel gibt, dann trägt er den Namen [Schlüssel]Default, also z.B. "NameDefault" (sowas in der Art hatte ich ja schonmal gesagt).
    - Wenn darauf Verlass ist, kannst du vor dem Einlesen (oder auch dem Löschen) eines Schlüssels erstmal versuchen, den Defaultwert einzulesen (den Schlüsselnamen kannst du dir ja schön string-mäßig zusammenbasteln, da die feste Regel Schlüsselname+"Default" gilt).
    - Ist dieser vorhanden, setzt du beim Löschen statt "" eben den gelesenen Defaultwert.

    Passt doch. Und ist fast das, was du willst, oder?

    Ergänzung: ich denke, es ist klar, erwähne es aber mal kurz. Wenn die Defaultwerte nicht unbedingt variabel sein müssen und auch die Schlüssel feststehen, zu denen es Defaultwerte gibt, kannst du dir den Quatsch natürlich sparen und es hartkodiert machen (über den Defaultstring bei GetPrivateProfileString).



  • Hallo Matze.
    Erstmal vielen Dank für deine Antworten und Mühe. Spitze!

    Ich kann die einzelnen Schlüssel nicht ändern, weil diese noch von anderen Programmen genutzt wird.
    Sprich, wenn ich irgendwo den Schlüsselnamen ändere, wird er in einer anderen Anwendung nicht erkannt.

    Deshalb habe ich es schon wie folgt hinbekommen.
    Vorweg: Es wird nachher die Kopie bearbeitet. Das Original bleibt immer unberührt.

    - Er kopiert die Datei Zeile für Zeile.
    - Dabei erkennt er die Defaults anhand von Kommentaren ";Standard:Defaultwert"
    - Bei der nächsten Zeile(Schlüssel), die er einliest setzt er nun vorm Schlüssel ein "**" davor und trägt den im Kommentar stehenden Defaultwert als Wert ein.
    - Ganz normale Schlüssel (wo er vorher kein Kommentar ;Standard:.... gefunden hat, übernimmt er einfach so.
    Also:

    Original.ini:
    [Section ABC]
    USER=Paul
    ;Standard:5487
    KEY=testwert123
    COLOUR:red
    ;Standard:100
    SPEED=55

    ....nun kopiere ich sie.....

    Kopie.ini
    [Section ABC]
    USER=Paul
    ;Standard:5487
    **KEY=5487
    COLOUR:red
    ;Standard:100
    **SPEED=100

    So, nun kommt der Teil mit GetProfilString etc...
    D.h. es werden alle Schlüsselwerte gelöscht.
    Nun hab ich da ne IF Abfrage reingebaut und gesagt...."lösche alle werte außer wenn vorm Schlüssel ein "**" steht.
    Klappt auch.
    Nun löscht er alles außer die mit **

    Einzige Problem ist nun, dass ich halt anschließend nur noch diese ** wegbekommen muss 🙂
    Because:

    Ich kann die einzelnen Schlüssel nicht ändern, weil diese noch von anderen Programmen genutzt wird.
    Sprich, wenn ich irgendwo den Schlüsselnamen ändere, wird er in einer anderen Anwendung nicht erkannt.

    Das war bisher mein Lösungsansatz. 😉



  • Das einzige, was mir nun dazu einfällt, wäre:

    -Die Kopie nochmal als String Zeile für Zeile einlesen und dann dabei die ** weglöschen.
    Aber mit PrivateProfilString gehts nicht.


  • Mod

    Claudiah schrieb:

    Das einzige, was mir nun dazu einfällt, wäre:

    -Die Kopie nochmal als String Zeile für Zeile einlesen und dann dabei die ** weglöschen.
    Aber mit PrivateProfilString gehts nicht.

    Sicher.
    Einfach die Einträge durchlaufen.
    Einen Eintrag mit ** neu eintragen ohne **
    Anschließend ** Eintrag löschen.



  • Martin Richter schrieb:

    Claudiah schrieb:

    Das einzige, was mir nun dazu einfällt, wäre:

    -Die Kopie nochmal als String Zeile für Zeile einlesen und dann dabei die ** weglöschen.
    Aber mit PrivateProfilString gehts nicht.

    Sicher.
    Einfach die Einträge durchlaufen.
    Einen Eintrag mit ** neu eintragen ohne **
    Anschließend ** Eintrag löschen.

    Aber mit PrivateProfileString gehts nicht oder?
    Hätte nun die Datei Zeile für Zeile als normalen String eingelesen und mit .find und .replace gearbeitet


  • Mod

    Warum nicht? Es geht ja hier nich tum einen Kommentar oder?
    Man kann mit WritePrivateProfileString werte ändern und Einträge löschen.
    Also geht es!



  • Martin Richter schrieb:

    Warum nicht? Es geht ja hier nich tum einen Kommentar oder?
    Man kann mit WritePrivateProfileString werte ändern und Einträge löschen.
    Also geht es!

    Kann ich auch den Schlüsselnamen ändern?


  • Mod

    Claudiah schrieb:

    Martin Richter schrieb:

    Warum nicht? Es geht ja hier nich tum einen Kommentar oder?
    Man kann mit WritePrivateProfileString werte ändern und Einträge löschen.
    Also geht es!

    Kann ich auch den Schlüsselnamen ändern?

    Oh Mann! NEIN!

    Aber Du kannst
    1. einfach einen Wert lesen,
    2. unter einem neuen Schlüssel eintragen
    3. und den alten löschen!


Anmelden zum Antworten