Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi .ini Datei Schlüssel aller Abschnitte zählen (https://www.delphipraxis.net/169006-ini-datei-schluessel-aller-abschnitte-zaehlen.html)

Drahcir 22. Jun 2012 23:43

.ini Datei Schlüssel aller Abschnitte zählen
 
ich habe erneut ein Problem, wieder mit .ini-Dateien.

Es geht drum aus einem .ini-file aus einer unbekannten anzahl Abschnitte die anzahl aller Schlüssel auszulesen.

Mein Ansatz ist, alle Abschnitte in eine Stringlist zu laden, diese Name für name die Schlüssel zählen zu lassen und nach jedem Abschnitt auf eine Variable zu addieren.

Es funktioniert aber leider nicht und ich erhoffe mir hier zumindest einen ansatz wo mein Denkfehler ist :)

Delphi-Quellcode:
var sl1, sl2 : TStringlist;
    I, Anzahl : Integer;
    LogInIni : TIniFile;
begin
//Ini-Datei wird ordnungsgemäß angelegt und auch schon vorher verwendet

  sl1 := TStringList.Create; sl2 := TStringList.Create;
  sl1 := nil; sl2 := nil;
  Anzahl := 0;
  LogInIni.ReadSections(sl1);

  for I := 1 to sl1.Count do begin
    LogInIni.ReadSection(sl1[I], sl2);
    Anzahl := Anzahl + sl2.count;
  end;

  hLogInFenster.Label1.Caption := IntToStr(Anzahl);

//Ini-Datei wird ordnungsgemäß freigegeben und zum Schluss gelöscht
Ich vermute sehr stark, das der Fehler in der Zeile liegt:

Delphi-Quellcode:
LogInIni.ReadSection(sl1[I], sl2);
Warscheinlich ist der Ausdruck
Delphi-Quellcode:
sl1[I]
falsch, aber ich hab keine Ahnung wie ich die sonst ansprechen soll ...

Vielen Dank im vorraus für Hilfe :)

himitsu 23. Jun 2012 00:14

AW: .ini Datei Schlüssel aller Abschnitte zählen
 
Wie bei fast allen Listen, fängt die Zählung bei 0 an. :roll:

Delphi-Quellcode:
for I := 0 to sl1.Count - 1 do




Tipp: Das nächste Mal nimmst du dir den Debugger und/oder schaust genau(er) hin, was wirklich ausgelesen und verarbeitet wird.
Denn sonst wäre dir bestimmt aufgefallen, daß du im ersten Schleifen-Durchgang den Namen der zweiten Sektion bekommen hast. :zwinker:



Zitat:

Delphi-Quellcode:
sl1 := TStringList.Create; sl2 := TStringList.Create;
sl1 := nil; sl2 := nil;

Ähhhhhhhhh?

Zitat:

Es funktioniert aber leider nicht
WAS funktioniert nicht?
Gibt es denn keine Fehlermeldungen oder eine genauere Fehlerbeschreibung? (z.B. was passert und was erwartest du stattdessen)

Zitat:

Delphi-Quellcode:
//Ini-Datei wird ordnungsgemäß freigegeben und zum Schluss gelöscht

Auch die Stringlisten? (so wie es aussieht, können diese garnicht mehr freigegeben werden, egal was man macht ... siehe dein Code aus dem vorletzen Zitat)

Und Resourcenschutzblöcke sieht man auch nicht.

Drahcir 23. Jun 2012 00:57

AW: .ini Datei Schlüssel aller Abschnitte zählen
 
Zitat:

Zitat von himitsu (Beitrag 1172100)
Wie bei fast allen Listen, fängt die Zählung bei 0 an. :roll:

Delphi-Quellcode:
for I := 0 to sl1.Count - 1 do

Hab ich geändert, hast natürlich recht :)


Zitat:

Zitat von himitsu (Beitrag 1172100)
Zitat:

Delphi-Quellcode:
sl1 := TStringList.Create; sl2 := TStringList.Create;
sl1 := nil; sl2 := nil;

Ähhhhhhhhh?

Ja öhm ... keine Ahnung was mich da geritten hat aber das das so nicht funzt ist schon klar ... habs geändert (entfernt).

Zitat:

Zitat von himitsu (Beitrag 1172100)
Zitat:

Es funktioniert aber leider nicht
WAS funktioniert nicht?
Gibt es denn keine Fehlermeldungen oder eine genauere Fehlerbeschreibung? (z.B. was passert und was erwartest du stattdessen)

Es gibt (nach entfernung der nil-probleme weiter oben) keine Fehlermeldung aber als Anzahl schlüssel bekomme ich immer 0 heraus :(

Zitat:

Zitat von himitsu (Beitrag 1172100)
Zitat:

Delphi-Quellcode:
//Ini-Datei wird ordnungsgemäß freigegeben und zum Schluss gelöscht

Auch die Stringlisten? (so wie es aussieht, können diese garnicht mehr freigegeben werden, egal was man macht ... siehe dein Code aus dem vorletzen Zitat)

Und Resourcenschutzblöcke sieht man auch nicht.

doch die sind da, nur weiter vorne und weiter hinten in der Prozedur die ich auf wunsch auch vollständig hier rein stelle wenns gewünscht ist ;)

Waran liegt es, das ich immer 0 als Ergebnis bekomme?

Bummi 23. Jun 2012 06:34

AW: .ini Datei Schlüssel aller Abschnitte zählen
 
Delphi-Quellcode:
  for I := 0 to sl1.Count -1 do
  begin
    LogInIni.ReadSectionValues(sl1[I], sl2);
    Anzahl := Anzahl + sl2.count;
  end;

Drahcir 23. Jun 2012 07:41

AW: .ini Datei Schlüssel aller Abschnitte zählen
 
Liste der Anhänge anzeigen (Anzahl: 1)
es tut mir leid aber das funktioniert immer noch nicht >.> ich hau hier jetzt einfach mal den ganzen quelltext samt fehlermeldung die dabei entsteht rein
(Ja ich weiß ich hab ne komische Art der Sortierung...):

Delphi-Quellcode:
procedure TfrmMain.btLogInsClick(Sender: TObject);
var I, Zeile, Anzahl : Integer; LogInIni : TIniFile;
    Ein, Datum, DatumAusgelesen, Uhrzeit, Koordinaten, LogIns : string;
    sl1, sl2 : TStringlist;
begin
  hLogInFenster := TfrmLogInAnzeige.Create(frmMain);
  hLogInFenster.Left := frmMain.Left + frmMain.Width + 20;
  hLogInFenster.Top := frmMain.Top;

  for Zeile := 0 to hLogFenster.MemoLogAnzeige.Lines.Count-1 do begin
    ein := Utf8ToAnsi(hLogFenster.MemoLogAnzeige.Lines[Zeile]);

    if (pos(cbSpieler.Text, Ein) <> 0)              //In einer TCombobox eingetragener Wert
    AND (pos('logged in with entity id', ein) <> 0) //Ein weiteres "SuchWort" im Text
    then begin
      {*** Uhrzeit ***}
      for I := 12 to 19 do Uhrzeit := Uhrzeit + ein[I];
      DatumAusgelesen := leftStr(Ein,10);

      {*** Datum ***}
      for I := 9 to 10 do Datum := Datum + DatumAusgelesen[I]; Datum := Datum + '.';
      for I := 6 to 7 do Datum := Datum + DatumAusgelesen[I]; Datum := Datum + '.';
      for I := 1 to 4 do Datum := Datum + DatumAusgelesen[I];
      hLogInFenster.cbLogins.Items.Add(Datum);                 //eintragen der Daten in eine TCombobox

      {*** Koordinaten ***}
      Koordinaten := copy(Ein, pos('(',Ein)+1,200);
      Delete(Koordinaten,pos(')',Koordinaten),1);

      {*** Eintragen des Datums, Uhrzeit und Koordinaten in die .ini ***}
      try LogIns := ExtractFilePath(ParamStr(0)) + 'LogIns.ini';
          LogInIni := TIniFile.Create(LogIns);
          LogInIni.WriteString(Datum, Uhrzeit, Koordinaten);
      finally LogInIni.Free; end;

      {*** Zurücksetzen der Variablen ***}
      Uhrzeit := ''; Datum := ''; Datumausgelesen := '';
    end;

    {*** Löschen doppelter Einträge ***}
    for I := 0 to hLogInFenster.cbLogIns.Items.Count - 1 do
      if hLogInFenster.cbLogIns.Items[i] = hLogInFenster.cbLogIns.Items[i+1]
      then hLogInFenster.cbLogIns.Items.Delete(i);
  end;

  {****** Hier hat das Programm Probleme ... *****}
  sl1 := TStringList.Create; sl2 := TStringList.Create;
  Anzahl := 0;
  LogInIni.ReadSections(sl1);

  for I := 0 to sl1.Count - 1 do begin
    LogInIni.ReadSection(sl1.Strings[I], sl2); // Ich denke mal hier liegt das Problem mit Schreiben nach sl2
    Anzahl := Anzahl + sl2.Count;
  end;

  hLogInFenster.Label1.Caption := IntToStr(Anzahl);
  {****** *****}

  hLogInFenster.Show;
end;
Ich denke mal der Fehler taucht an der Stelle auf wo ich
Delphi-Quellcode:
LogInIni.ReadSection(sl1.Strings[I], sl2);
eintragen lasse, da er in der Klammer TStrings haben möchte, sl2 aber eine TStringList ist.
Wenn ich das so Laufen lasse gibts als Anzahl 0 zurück, wenn ich
Delphi-Quellcode:
LogInIni.ReadSectionValues(sl1[I], sl2);
mache gibts die angehängte Fehlermeldung.

Vielen Dank für die ersten Hilfen schonmal

Bummi 23. Jun 2012 08:40

AW: .ini Datei Schlüssel aller Abschnitte zählen
 
1. LogInini wird gar nicht garantiert erzeugt
2. Logini wird wenn sie erzeugt wurde zumindest wieder freigegeben
ein Zugriff darauf ist also gar nicht zulässig

3. hier greifst du auf Items außerhalb der Liste zu
Delphi-Quellcode:
for I := 0 to hLogInFenster.cbLogIns.Items.Count - 1 do
      if hLogInFenster.cbLogIns.Items[i] = hLogInFenster.cbLogIns.Items[i+1]
4. Löschen in Listen immer rückwärts
Delphi-Quellcode:
for I := hLogInFenster.cbLogIns.Items.Count - 1 downto 0 do

5. sl1 und sl2 werden nicht freigegeben

6. Das Parsen ist ineffizient und potentiell wird hier auch auf ungültige Adressen zugegriffen

den Fehler laut Anhang kann ich nicht mit dem Zugriff in Zusammenhang bringen

Drahcir 23. Jun 2012 08:59

AW: .ini Datei Schlüssel aller Abschnitte zählen
 
Vielen Dank, das Problem war wirklich das ich erst die ini freigebe und dann versuche drauf zuzugreifen, nachdem ich das .free ans ende gestetzt habe funktioniert es :)

hab auch sl1 und sl2 nun freigeben lassen und mit downto hast du natürlich auch recht, zumindest das hätte mir auffallen müssen.

Hab das Erzeugen der Datei nun auch an den Anfang gestellt damit das gewährleistet ist.

Zitat:

6. Das Parsen ist ineffizient und potentiell wird hier auch auf ungültige Adressen zugegriffen
Ok das versteh ich jetzt mal gar nicht >.>

Aber trotzdem danke, das Problem ist nun gelöst, wenn du mir noch die Frage beantworten magst wärs nett :)

Sir Rufo 23. Jun 2012 09:20

AW: .ini Datei Schlüssel aller Abschnitte zählen
 
Anstatt nachher auf doppelte Einträge zu prüfen, könntest du auch schon vor dem Eintragen prüfen, ob es den Eintrag schon gibt.

Delphi-Quellcode:
if hLogInFenster.cbLogins.Items.IndexOf( Datum ) < 0 then
 hLogInFenster.cbLogins.Items.Add(Datum);

Bummi 23. Jun 2012 09:58

AW: .ini Datei Schlüssel aller Abschnitte zählen
 
statt mit Schleifen über z.B. ein[I] den String zusammenzubasteln, was schief geht wenn z.B. "ein" kürzer wäre als erwartet könntest Du Dir mal COPY anschauen ...

himitsu 23. Jun 2012 11:00

AW: .ini Datei Schlüssel aller Abschnitte zählen
 
Zitat:

Delphi-Quellcode:
procedure TfrmMain.btLogInsClick(Sender: TObject);
begin
  ...
  for Zeile := 0 to hLogFenster.MemoLogAnzeige.Lines.Count-1 do begin
    ...
    if ... then begin
      ...

      {*** Eintragen des Datums, Uhrzeit und Koordinaten in die .ini ***}
      try LogIns := ExtractFilePath(ParamStr(0)) + 'LogIns.ini';
          LogInIni := TIniFile.Create(LogIns);
          LogInIni.WriteString(Datum, Uhrzeit, Koordinaten);
      finally LogInIni.Free; end;
      ...
    end;
    ...
  end;
  ...
  LogInIni.ReadSections(sl1);
  for I := 0 to sl1.Count - 1 do begin
    LogInIni.ReadSection(sl1.Strings[I], sl2);
    Anzahl := Anzahl + sl2.Count;
  end;
  ...
end;

Theoretisch würde ich hier erwarten, daß Delphi mir in den Compilermeldungen etwas von wegen "Variable nicht initialisiert" um die Ohren haut.

Das LogInIni wird nur innerhalb der der Schleife und in dem IF initialisiert, also wenn es dort nie vorbeikommt, dann kann es danach nicht initialisiert sein.
Außerdem wird es da in der Schleife nicht nur initialisiert, sonder auch gleich wieder freigegeben, womit es nach der Schleife auch wieder nicht mehr vorhanden ist.


An deiner Stelle würde ich zukünftig nie wieder .Free (erst garncht .Destroy), sondern nur noch FreeAndNil verwenden.

PS:
Zitat:

Delphi-Quellcode:
      try LogIns := ExtractFilePath(ParamStr(0)) + 'LogIns.ini';
          LogInIni := TIniFile.Create(LogIns);
          LogInIni.WriteString(Datum, Uhrzeit, Koordinaten);
      finally LogInIni.Free; end;

Die Initialisierung gehört niemals in den Schutzblock :!:

Denn was passiert, wenn es beim Initialisieren (Erstellen des Objektes) knallt?
Genau, es kanllt im Finally auch nochmal.
Delphi-Quellcode:
LogIns := ExtractFilePath(ParamStr(0)) + 'LogIns.ini';
LogInIni := TIniFile.Create(LogIns); // kurz vorm Try erstellen (dazwischen darf kein "gefährlicher" Code mehr kommen)
try
  LogInIni.WriteString(Datum, Uhrzeit, Koordinaten);
finally
  LogInIni.Free;
end;

// oder

LogInIni := nil; // erstmal als "leer" initialisieren
try
  LogIns := ExtractFilePath(ParamStr(0)) + 'LogIns.ini'; // das kann in oder vor dem Try stehen
  LogInIni := TIniFile.Create(LogIns); // und später erstellen (wird im es Try-Finally nochmal freigegeben, dann nur mit FreeAndNil freigeben+finalisieren)
  LogInIni.WriteString(Datum, Uhrzeit, Koordinaten);
finally
  LogInIni.Free;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:19 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz