ini Key immer ein wert größer (++)



  • Morgen zusammen,

    ich hab das Problem das ich durch einen Button klick einen eintrag in eine Ini schreiben will:

    int i=0;
    TIniFile *ini = new TIniFile(FileName);
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    
    ini->WriteString("Name",i,(LabeledEdit1->Text));
    
    }
    

    das ganz soll halt einträge in der Sektion "Name" schreibnen und halt wie folgt:

    [Name]
    1=Hans
    2=peter
    3=balbal
    usw.

    jemand ne idee wie ich dieses problem lösen kann =?



  • was genau ist das Problem?

    mal davon abgesehen, dass es vielleicht besser ist das i in der WriteString-Anweisung in einen String umzuwandeln ->InToStr(i)



  • i++;
    ini->WriteString("Name",IntToStr(i),(LabeledEdit1->Text));
    

    gut also es geht das dumme ist bei jedem neuen Stzart des programms überschreibt er die alten wete er fängt nicht an der letzten stelle an. sprich wenn ich schon 3 strings hab die den key 1,2,3 habe und bei nächsten prgramm start soll es bei 4 weiter machen aber er überschreibt 1 ganz normal.

    wie verhinder ich das am besten jemand nen tip ?


  • Mod

    Hallo

    merk dir einfach den Wert 😃
    (zB in deiner INI)

    MfG
    Klaus



  • der wert ist doch in der ini in müste doch einfach nur : wenn ich den button klicke müss er prüfen welcher der letzte eintrag in dem Sektor [Name] ist und den Key zb. 5 nehmen und damit weiter ++ rechnen.



  • Dann lies halt einfach alle Bezeichner aus und weise i dann den höchsten Wert von denen zu...



  • gut verstanden, wie kann ich aber nur der Schlüssel auslesen lassen ?
    if(ini->ReadSection("Name"...?????...) ???



  • hi, ich glaube, so müssts gehen:

    #include <IniFile.h> //oder so ähnlich
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      TIniFile *ini=new TIniFile(FileName);
      for(int i=1;i<1000;i++) //das müsste reichen *g*
        if(ini->ReadString("Name",IntToStr(i),NULL))
          int x=i;
      ini->WriteString("Name",x++,(LabeledEdit1->Text));
      delete ini; //WICHTIG
    }
    

    bin mir aber nich sicher



  • Schau dir doch mal die Methode ReadSectionValues von TIniFile an. Da bekommst du alle Keys zurück und kannst den höchsten ermitteln.

    Gruß Skay



  • Blackhawk schrieb:

    hi, ich glaube, so müssts gehen:

    #include <IniFile.h> //oder so ähnlich
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      TIniFile *ini=new TIniFile(FileName);
      for(int i=1;i<1000;i++) //das müsste reichen *g*
        if(ini->ReadString("Name",IntToStr(i),NULL))
          int x=i;
      ini->WriteString("Name",x++,(LabeledEdit1->Text));
      delete ini; //WICHTIG
    }
    

    bin mir aber nich sicher

    das dürfte eine Fehlermeldung bringen, da das x nicht bekannt ist in der WriteString-Answeisung...

    |23| schrieb:

    gut verstanden, wie kann ich aber nur der Schlüssel auslesen lassen ?
    if(ini->ReadSection("Name"...?????...) ???

    statt der ????? solltest du eine StringListe schreiben und dann erhälst du mit Count die Anzahl der in der Section enthaltenen Einträge

    als Bespiel:

    TStringList *sList = new TStringList;
    ini->ReadSection("Name", sList);
    i = sList->Count; 
    delete sList;
    


  • nur als anmerkung:

    i=sList->Count+1;
    

    sonst überschreibst du den letzten eintrag



  • ini->ReadSection("Name",sList);
    int i = sList->Count+1;
    delete sList;
    ini->WriteString("Name", IntToStr(sList),(LabeledEdit1->Text));
    delete ini;
    

    geht ned



  • Hast du schonmal programmiert? Kannst du dir eventuell vorstellen, dass...

    1. sList kein Integer sondern TStringList ist, die Funktion einen Integer erwartet
    2. sList zuvor gelöscht wurde, mit delete...

    Es muss also heißen:

    ini->ReadSection("Name",sList);
    int i = sList->Count+1;
    delete sList;
    ini->WriteString("Name", IntToStr(i),LabeledEdit1->Text);
    delete ini;
    

    Wobei delete ini vielleicht nicht so toll ist, wenn du nämlich nochmal auf den Button klickst, wird dein Objekt ini weg sein... und eine Zugriffsverletzung auftreten. Mach das delete ini; lieber in OnCloseQuery der Form.



  • Ausbildung zum Fachinformatiker - Anwendungsentwicklung <- irgendwie glaub ich immer weniger dran... tut mir leid, is aber so. wie lange bist du schon in der ausbildung?



  • @Blackhawk
    jetzt genau 3 wochen.
    seit 2 wochen an c++ und zuvor keine andere Programmiersprache gelernt.

    @Windoof

    1. hab wohl aus furst dumme fehler gemacht! weiss jetzt auch nicht wirklich wie ich drauf komme IntToStr zu schreiben da es ja StrToInt sein muss

    2. hast vollkommen recht

    trotzdem geht das immer noch nicht. jetzt überschreib er einfach den ersten wert und gut ist..



  • kk dann is ok
    ich bin jetz in der 8. woche
    aber keine ausbildung
    hobby halt



  • Danke das keine merh geantwortet hat, den ich hab es geschaft also jetzt geht es sauber und die lösung war so einfach.. das sagt mir das ich noch mehr lernen muss(und will).

    Lösung

    if(LabeledEdit1->Text =="")
      {
      Application->MessageBox("Bitte tragen Sie einen Namen in das Feld ein.","Keine Einträge", MB_OK);
      }
      else if(LabeledEdit2->Text == "")
       {
       Application->MessageBox("Bitte Tragen Sie einen Nummer in das Feld ein.","Keine Einträge", MB_OK);
       }
      else
        {
        ini->ReadSection("Name",sList);
        int g1 = sList->Count+1;
        for(int i = 0; i < g1 ; i++)
        ini->WriteString("Name", g1,(LabeledEdit1->Text));
    
        ini->ReadSection("Nummer",sList);
        int g2 = sList->Count+1;
        for(int i = 0; i < g2 ; i++)
        ini->WriteString("Nummer", g2,(LabeledEdit2->Text));
    
        Application->MessageBox("Der Eintrag wurde gespeichert","Gespeichert", MB_OK);
        }
    


  • Also Ziel ist es ja, den Quelltext so kurz wie möglich und doch übersichtlich zu halten, und das Programm zu optimieren, auf Geschwindigkeit, etc. Es wird sich bei dem Code vermutlich nicht bemerkbar machen, aber schreib das hier statt deinem Code hin:

    if (LabeledEdit1->Text!="" && LabeledEdit2->Text!="")
    {
      ini->ReadSection("Name",sList);
      ini->WriteString("Name",IntToStr(sList->Count+1),LabeledEdit1->Text);
      ini->ReadSection("Nummer",sList);
      ini->WriteString("Nummer",IntToStr(sList->Count+1),LabeledEdit2->Text);
      Application->MessageBox("Der Eintrag wurde gespeichert","Gespeichert",MB_OK);
    }
    else
    {
      Application->MessageBox("Bitte alle Felder ausfüllen.","Fehler",MB_OK);
    }
    

    Folgende Änderungen:

    - Keine Extra-Integer-Variablen verwendet
    - Keine for-Schleifen, die unnötig waren
    - Korrekte Umwandlung von Integer zu AnsiString
    - Quelltext kurz und übersichtlich gehalten



  • Zum Gesamtansatz: Es hat natürlich ein bischen was von Glücksspiel, sich darauf zu verlassen, dass die Zahl der Einträge in einem Abschnitt auch mit der höchsten vergebenen Nummer übereinstimmt (von der Reihenfolge mal ganz abgesehen).
    Schliesslich sind das einfache Textdateien, in denen Einträge leicht manuell gelöscht, geändert oder umgruppiert werden können.

    Wenn man jedoch davon ausgeht, dass die Integrität der Daten garantiert ist, dann kann man auf das zweite ReadSection auch verzichten, da logischerweise beide Listen immer gleich lang sein müssen.



  • Windoof schrieb:

    Also Ziel ist es ja, den Quelltext so kurz wie möglich und doch übersichtlich zu halten,

    Falsch...
    Es ist wichtig ein Programm so übersichtlich wie möglihc. Aber nur so kurz wie nötig zu machen.
    Optimieren tut dein Compiler schon. Da brauchste nur selten dem Teil unter die Arme zu greifen. Der Compiler kann das ohnehin (meist) besser als der Programmierer.
    wennde selber alle Optimierungen machen willst, dann fang an assembler zu programmieren.

    Aktionen wie

    Windoof schrieb:

    - Keine Extra-Integer-Variablen verwendet

    zum Beispiel sorgen eher für mangelnde Übersichtlichkeit und massiv erschwertes Debugging.

    Windoof schrieb:

    - Quelltext [...] übersichtlich gehalten

    N.E.F. aka. Nicht Erfüllt!

    -junix


Anmelden zum Antworten