ReadString

Zur Vorstellung von Komponenten und Units für Lazarus
Benutzeravatar
Maik81SE
Beiträge: 308
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
CPU-Target: x86-64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

ReadString

Beitrag von Maik81SE »

Moin @ll

ich weiß nicht, ob ich mich bezüglich der ReadString Funktionen auf einem Holzweg befinde.

ich versuche via folgendem Code

Code: Alles auswählen

      for a:= 0 to Temp.Count - 1 do begin
        s:= Format('[%s]', ['Artikel' + IntToStr(a + 1)]);
        if (ReadString(s, 'Bezeichnung', '') <> '') then begin
           fArtikel[b].index               := ReadInteger(s, 'Lfd-Nr.:', 0);
           fArtikel[b].Bezeichnung         := ReadString(s, 'Bezeichnung', '');
           fArtikel[b].Klassifizierung     := ReadString(s, 'Klassifizierung', '');
           fArtikel[b].Version             := ReadString(s, 'Version', '');
           fArtikel[b].Beschaffung         := ReadString(s, 'Beschaffungsliste', '');
           inc(b);
           inc(Index);
           end;
        end;

Eine Abfrage zu erwirken ob der Wert den ich lesen will auch vorhanden ist. (Bug Killer)

Aber während ich das gerade schreibe, Klaube ich mir die Antwort selber zu geben, möchte aber mal noch andere Meinugen lesen, ob mein Holzweg mit folgendem Ansatz richtig verlassen wird ;) :D

Code: Alles auswählen

      for a:= 0 to Temp.Count - 1 do begin
        s:= Format('[%s]', ['Artikel' + IntToStr(a + 1)]);
        if (ReadString(s, 'Bezeichnung', '') <> 'Bezeichnung=') then begin
           fArtikel[b].index               := ReadInteger(s, 'Lfd-Nr.:', 0);
           fArtikel[b].Bezeichnung         := ReadString(s, 'Bezeichnung', '');
           fArtikel[b].Klassifizierung     := ReadString(s, 'Klassifizierung', '');
           fArtikel[b].Version             := ReadString(s, 'Version', '');
           fArtikel[b].Beschaffung         := ReadString(s, 'Beschaffungsliste', '');
           inc(b);
           inc(Index);
           end;
        end;
 


Wie immer bin ich für jeden Tip Dankbar.

Grüße aus China Maik

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.0.0.3 FPC 3.2.2);
windows 10 (L 3.99.0.0 FPC 3.2.0)

Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: ReadString

Beitrag von Komoluna »

Warum startest du 2 Threads?
Reicht einer nicht?
Wenn du der Meinung bist, im falschen (Unter-)Forum gepostet zu haben, kannst du einen Moderator/Administrator bitten den Thread zu verschieben.

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: ReadString

Beitrag von wp_xyz »

Im Vergleich zu dem anderen Thread sehe ich, dass du den Text geändert hast. Dazu musst du aber keinen neuen Thread anfangen, sondern du kannst den bereits eingegebenen mit Hilfe des Schalters "Ändern" editieren.

Benutzeravatar
Maik81SE
Beiträge: 308
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
CPU-Target: x86-64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Re: ReadString

Beitrag von Maik81SE »

Nun... Das hab ich leider auch erst zu spät mitbekommen, das GC. sponn...

Aber Leider sind eure Meinungen nur ein Posthinweis aber nicht das, wonach ich gefragt hab.

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.0.0.3 FPC 3.2.2);
windows 10 (L 3.99.0.0 FPC 3.2.0)

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: ReadString

Beitrag von wp_xyz »

Aber leider ist deine Fragestellung unvollständig. Eine Funktion ReadString gibt es m.E. nicht (nur als Methode einer Klasse wie TIniFile etc.). Du musst schon genau beschreiben, was du meinst, wir sind keine Hellseher.

shokwave
Beiträge: 470
Registriert: Do 15. Nov 2007, 16:58
OS, Lazarus, FPC: Win11/Ubuntu Budgie (L 3.0 FPC 3.2.2)
CPU-Target: i386, x64
Wohnort: Gera

Re: ReadString

Beitrag von shokwave »

Hallo Maik,

ich mutmaße mal das es um eine INIDatei geht und denke der Fehler liegt hier

Code: Alles auswählen

s:= Format('[%s]', ['Artikel' + IntToStr(a + 1)]);

Der Sektionsname wird ohne Klammern geschrieben, auch wenn er in der Datei mit Klammern steht.
mfg Ingo

ruewa
Beiträge: 153
Registriert: Sa 12. Apr 2014, 14:43

Re: ReadString

Beitrag von ruewa »

wp_xyz hat geschrieben:Aber leider ist deine Fragestellung unvollständig.


wp_xyz hat recht! Da Du aber drei Strings als Parameter übergibst, kann eigentlich nur T(Custom)IniFile.ReadString/-Integer etc. gemeint sein. Dein Code kann dann nur funktionieren, wenn Du ihn in ein "With MyIniFile do Begin ... end;" eingepackt hast, richtig? Um Deinen Code für andere verständlich zu machen, hättest Du das und die Variablendeklarationen noch mit rein packen müssen.

Das angenommen, wäre Deine erste Variante (if MyIniFile.ReadString() <> '' then ...) richtig, Deine zweite (if MyIniFile.ReadString() <> 'Name=' then ...) falsch, denn diese IniFile-Funktion liefert den reinen Wert zurück und abstrahiert von der internen Darstellung in der Ini-Datei.

Kommst Du denn mit der Lazarus-Hilfe zurecht? Deren Benutzung ist unverzichtbar, um solche Fragen zu klären! Setz enfach den Cursor auf "MyIniFile.ReadString" und drücke "F1", dann müßtest Du eigentlich schon auf der richtigen Seite landen (notfalls mußt Du Dich noch zur "ReadString"-Seite durchklicken). Da kannst Du dann folgendes lesen:

Code: Alles auswählen

ReadString reads the key Ident in section Section, and returns the value as a string. If the specified key or section do not exist, then the value in Default is returned. Note that if the key exists, but is empty, an empty string will be returned. 

Es ist also noch ein bißchen komplizierter: Die Funktion kann Dir einmal einen schon vorhandenen Wert zurückliefern, dann einen leeren String oder drittens Deinen Default-Wert (In Deinem Fall laufen der Leerstring und der Defaultwert auf dasselbe hinaus, das muß aber nicht immer so sein).

Wenn Dein Programm mit größeren Datenmengen umgehen müßte, wäre ein IniFile sicher nicht die beste Art, Daten zu speichern, aber ich nehme an, Du übst erst mal an einem kleinen Projekt. Da kannst Du das schon so machen.

Aber wie auch immer: Versuche zu verstehen, warum Deine Fragestellung so unklar war, und vor allem solltest Du lernen, die Hilfe-Funktion von Lazarus ausgiebig zu benutzen!

Gruß Rüdiger

Edit: Stimmt, shokwave hat auch recht, bei "s:= Format('[%s]', ['Artikel' + IntToStr(a + 1)]);" kommt für a=3 dann s='[Artikel4]' (in eckigen Klammern) raus. Die format-Anweisung nützt Dir eigentlich gar nichts, sie verkompliziert die Sache nur unnötig und ist sehr fehleranfällig. Ein "s := 'Artikel' + IntToStr(a+1);" würde es genauso tun (dann ohne Klammer). Schau Dir mal die Hilfe-Seite für die Format-Funktion an, das Zeug ist ziemlich kompliziert und nicht leicht zu verstehen. Solange Du noch keine Erfahrung mit dem Debugger hast und nicht weißt, wie Du es anstellen mußt, um das Egebnis von s in dieser Zeile zu überprüfen, mach besser erstmal einen großen Bogen um Format().

Benutzeravatar
Maik81SE
Beiträge: 308
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
CPU-Target: x86-64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Re: ReadString

Beitrag von Maik81SE »

Was die Hilfe angeht... Dafür müste ich die erst mal zum laufen bekommen :|

Das andere was gemeint ist:

Code: Alles auswählen

procedure TArt.GetArtikel;
var Temp : TStringlist;
    s    : String;
    a, b : int64;
begin
  if FileExists(fPath + fFilename) then begin
    with TIniFile.Create(fFilename) do try
      Temp:= TStringlist.Create; try
      ReadSections(Temp);
      SetLength(fArtikel, Temp.Count);
      b:= 0;
      for a:= 0 to Temp.Count - 1 do begin
        s:= Format('[%s]', ['Artikel' + IntToStr(a + 1)]);
        if (ReadString(s, 'Bezeichnung', '') <> '') then begin
           fArtikel[b].index               := ReadInteger(s, 'Lfd-Nr.:', 0);
           fArtikel[b].Bezeichnung         := ReadString(s, 'Bezeichnung', '');
           fArtikel[b].Klassifizierung     := ReadString(s, 'Klassifizierung', '');
           fArtikel[b].Version             := ReadString(s, 'Version', '');
           fArtikel[b].Beschaffung         := ReadString(s, 'Beschaffungsliste', '');
           inc(b);
           inc(Index);
           end;
        end;
      SetLength(fArtikel, Index + 1);
      finally
        Temp.Free;
      end;
    finally
      Free;
    end;
  end;
  inc(index);
end;
 


Was ich in dieser Funktion machen will, leere Daten Filter, das mit sich keine Leichen in der Datenbank verirren können, deshalb habe ich mich bewust auch für den Typ INT64 entschieden.

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.0.0.3 FPC 3.2.2);
windows 10 (L 3.99.0.0 FPC 3.2.0)

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: ReadString

Beitrag von wp_xyz »

Oh Mann - lass dir doch nicht alles aus der Nase ziehen: was ist das Problem? Was geht nicht?

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: ReadString

Beitrag von theo »

Kleiner Tipp von mir: Lass das "with..do" Konstrukt immer und grundsätzlich weg. Das ist Teufelszeug und für Anfänger schon mal gar nicht geeignet.

Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: ReadString

Beitrag von Komoluna »

genau meine Meinung, das verwirrt nur.
Es erspart einem ein wenig Tipparbeit, aber kostet dafür ewig Zeit beim Fehlersuchen.
(kleiner Tipp: wenn du wenig tippen willst, nimm kurze Variablennamen, z.B.: Ini für ein TIniFile oder sl für TStringlist)

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: ReadString

Beitrag von wp_xyz »

Mir fallen zwei Stellen an dem Code auf:

Code: Alles auswählen

 
  if FileExists(fPath + fFilename) then begin
    with TIniFile.Create(fFilename) do try

Wenn du bei "FileExists" den Pfad mit zum Dateiname hinzufügst, und der Pfad kein Leerstring ist, liegt die Datei nicht im aktuellen Verzeichnis. Die Ini-Datei wird aber immer im aktuellen Verzeichnis gesucht - ich denke, es fehlt bei der Ini-Datei die Pfad-Angabe: TIniFile.Create(fPath + fFileName)

Code: Alles auswählen

 
s := Format('[%s]', ['Artikel' + IntToStr(a + 1)]);

Wie shokwave oben schon bemerkt hat, erwartet die Ini-Datei den Schlüssel nicht in eckigen Klammern. In der Format-Anweisung muss es daher heißen "%s" statt "[%s]".

[EDIT]
Diese Format-Anweisung kann man übrigens auch so schreiben:

Code: Alles auswählen

 
s := Format('Artikel%d', [a + 1]);
 

Benutzeravatar
Maik81SE
Beiträge: 308
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
CPU-Target: x86-64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Re: ReadString

Beitrag von Maik81SE »

theo hat geschrieben:Kleiner Tipp von mir: Lass das "with..do" Konstrukt immer und grundsätzlich weg. Das ist Teufelszeug und für Anfänger schon mal gar nicht geeignet.


Theo, Ich arbeite schon aus Prinzip mit mit with .. do und da du mir ja so freundlich davon abraten tust... Erst recht.
      A) Ist der einsatz jeweil Gut überlegt...
      B) Habe ich durch diese aus eigener Erfahrung wie wenigsten Objektfehler

wp_xyz hat geschrieben:Oh Mann - lass dir doch nicht alles aus der Nase ziehen: was ist das Problem? Was geht nicht?


Was das eigendliche Problem an dem Spaß ist?

Code: Alles auswählen

[[Artikel5]]
Lfd-Nr.:=5
Bezeichnung=CT2
Klassifizierung=xxyy.zz
Version=001122
Beschaffungsliste=
 
[[Artikel6]]
Lfd-Nr.:=6
Bezeichnung=
Klassifizierung=
Version=
Beschaffungsliste=
 
[[Artikel7]]
Lfd-Nr.:=7
Bezeichnung=CT_§
Klassifizierung=bhbjd
Version=cbdbvs
Beschaffungsliste=
Schaut in [[Artikel6]] und vergleicht [[Artikel7]] und [[Artikel5]]

Aber so viel Tam Tam nur um die Grundlegende Frage von euch bestädigt zu bekommen bzw. einen besseren Vorschlag, ob Bezeichnung= bei der Abfrage

Code: Alles auswählen

if (ReadString(s, 'Bezeichnung', '') <> '') then begin
lieber in die Abfrage

Code: Alles auswählen

if (ReadString(s, 'Bezeichnung', '') <> 'Bezeichnung=') then begin
zu ändern wäre. :|

wp_xyz hat geschrieben:Mir fallen zwei Stellen an dem Code auf:

Code: Alles auswählen

 
  if FileExists(fPath + fFilename) then begin
    with TIniFile.Create(fFilename) do try

Wenn du bei "FileExists" den Pfad mit zum Dateiname hinzufügst, und der Pfad kein Leerstring ist, liegt die Datei nicht im aktuellen Verzeichnis. Die Ini-Datei wird aber immer im aktuellen Verzeichnis gesucht - ich denke, es fehlt bei der Ini-Datei die Pfad-Angabe: TIniFile.Create(fPath + fFileName)


:shock: :shock: schitt... da fehlte noch der Path. :D
aber im den Eigentlichen Zielordner kümmere ich mich, wenn ich das Ganze für Wondoof Grosskompalieren... wird da via Registry verwaltet. bei Unix muß ich mit noch ein geeingetes Directory suchen.

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.0.0.3 FPC 3.2.2);
windows 10 (L 3.99.0.0 FPC 3.2.0)

ruewa
Beiträge: 153
Registriert: Sa 12. Apr 2014, 14:43

Re: ReadString

Beitrag von ruewa »

Hallo Maik!

Maik81SE hat geschrieben:Was die Hilfe angeht... Dafür müste ich die erst mal zum laufen bekommen :|

Oha! Wo ist denn da das Problem? Mit welcher Lazarus-Version und welchem Betriebssystem arbeitest Du denn? Normalerweise sollte die Hilfe bei jeder Standardinstallation aus dem Stand heraus verfügbar sein. Ich frage mich, wie man überhaupt mit Lazarus arbeiten kann, ohne die Sprachreferenz auf Tastendruck verfügbar zu haben? Also dieses Problem solltest Du zuallererst lösen!

Maik81SE hat geschrieben:

Code: Alles auswählen

 
    with TIniFile.Create(fFilename) do ...
 

Okay, als "Teufelszeug" würde ich die "with ... do"-Klammer nicht gleich verurteilen, aber in der Tendenz sehe ich das ähnlich wie die Vorredner. Der Preis für ein kleines bißchen Schreibfaulheit ist eine erhebliche Einschränkung der Klarheit und Lesbarkeit des Codes. Ich benutze "with ... do" selbst nur selten und nur an Stellen, die aus dem Kontext heraus leicht verständlich sind (z.B. in OnCreate-/OnDestroy-Prozeduren). Aber egal.

Was mich an Deinem Konstrukt erheblich mehr stört, ist, daß Du das IniFile in den luftleeren Raum hinein katapultierst! Der Compiler akzeptiert das, aber wo bleibt Dein IniFile, sobald Du den "with ... do"-Block verlassen hast? Wenn Du Deinem IniFile nicht einmal eine Variablendeklaration spendierst, kannst Du es, sobald Du den Block verlassen hast, nie wieder ansprechen! Wie willst Du Dein TIniFile-Objekt denn alleine schon freigeben, selbst wenn Du es hinterher nie mehr brauchen solltest? Das kannst Du so nicht machen, das ist ganz grober Unfug!

Maik81SE hat geschrieben:Aber so viel Tam Tam nur um die Grundlegende Frage von euch bestädigt zu bekommen...

Nun, ich habe Dir die Frage klipp und klar beantwortet! Und ich bezweifle, daß Dein Tonfall angemessen ist:

Maik81SE hat geschrieben:Theo, Ich arbeite schon aus Prinzip mit mit with .. do und da du mir ja so freundlich davon abraten tust... Erst recht.

Nimm's mir nicht übel, aber ich habe den Eindruck, daß Du Deine "Erfahrung" grotesk überschätzst, wenn Du auf derart banale Weise schon am Kleinen Einmaleins der Lazarus-/Pascal-Programmierung strandest! Das ist nichts Ehrenrühriges, jeder von uns hat mal ähnlich tapsig angefangen, aber mit überbordendem Selbstbewußtsein läßt sich das eben nicht aus der Welt reden!

Gruß Rüdiger

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: ReadString

Beitrag von m.fuchs »

Maik81SE hat geschrieben:Theo, Ich arbeite schon aus Prinzip mit mit with .. do und da du mir ja so freundlich davon abraten tust... Erst recht.
      A) Ist der einsatz jeweil Gut überlegt...
      B) Habe ich durch diese aus eigener Erfahrung wie wenigsten Objektfehler

Sorry, aber wenn dein Code so ist wie dein Schreibstil (und das ist wohl der Fall), dann ist der Einsatz nicht wohlüberlegt.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Antworten