| Autor |
Beitrag |
Gausi
      
Beiträge: 8553
Erhaltene Danke: 479
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Di 14.08.12 19:46
Ich hab da mal ne Frage, warum etwas nicht klappt, bzw. was da intern passiert. IDE ist Delphi 2009.
Ich habe einen Filestream, aus dem ich an einer bestimmten Stelle einen kurzen AnsiString (= 4 Zeichen lang) auslesen möchte.
Das habe ich zuerst so probiert:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| type TAtomName = String[4];
var AtomName: TAtomName; fs: TFileStream; fs.Read(AtomName[1], 4); |
Klappt aber nicht, d.h. AtomName ist leer. Mit fs.Read(AtomName[0], 4); wird der erwartete String ausgegeben, mit Aunahme des ersten Zeichens. Also statt "moov" nur ein "oov". Was ja irgendwie teilweise logisch ist...
Mit type TAtomName = AnsiString; und zusätzlichem SetLength(AtomName, 4); klappt es korrekt.
Ebenso klappt es mit type TAtomName = Array[1..4] of AnsiChar; - Die Lösung passt mir auch ganz gut, da ich mich nicht um SetLength etc. kümmern muss, und das Array of Char trotzdem mit einem String vergleichen kann.
Aber warum klappt es nicht mit dem ShortString? 
_________________ We are, we were and will not be.
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Di 14.08.12 20:55
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
Für diesen Beitrag haben gedankt: Gausi
|
|
Gausi 
      
Beiträge: 8553
Erhaltene Danke: 479
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Di 14.08.12 21:34
Ah, das erklärt das Verhalten  .
Initialisiert wird der String[4] mit 5 0-Bytes (4 Chars + Längenbyte). Wenn ich in die Chars was reinlese, bleibt das Längenbyte unberührt, und die Compilermagic bei Stringtypen-Konvertierungen guckt zuerst darauf, und nicht auf den eigentlichen Inhalt (wovon ich ausgegangen bin).
Danke, Frage geklärt. Dann bleib ich bei dem Array of Char, um mir das Setlength zu sparen. 
_________________ We are, we were and will not be.
|
|
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: Di 14.08.12 23:28
Begreifen tue ich das nicht.
Mit string[4] wird doch die (maximale) Stringlänge definiert?!
Typ(definition)en der Art "String[x]" kannte doch auch schon Turbo-Pascal, dem Setlength noch völlig fremd war.
|
|
jaenicke
      
Beiträge: 19339
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 15.08.12 06:03
Delphi-Laie hat folgendes geschrieben : | | Mit string[4] wird doch die (maximale) Stringlänge definiert?! |
Eben, die maximale, aber nicht die aktuelle. Das kannst du auch ganz leicht ausprobieren: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| type TAtomName = String[4]; var AtomName: TAtomName; begin ShowMessage(IntToStr(PByte(@AtomName[0])^)); AtomName := 'mo'; ShowMessage(IntToStr(PByte(@AtomName[0])^)); AtomName := 'moov'; ShowMessage(IntToStr(PByte(@AtomName[0])^)); end; | Zuerst wird 0, dann 2, dann 4 ausgegeben.
Delphi muss beim Auslesen des Strings ja wissen wie viele Zeichen da überhaupt gerade drin sind. Deshalb reicht die maximale Stringlänge als Information nicht aus.
Für diesen Beitrag haben gedankt: Delphi-Laie
|
|
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: Mi 15.08.12 14:14
Danke, aber ganz klar ist es immer noch nicht.
Das erste Byte ist das Längenbyte, und zwar für die aktuelle Länge (nicht die maximale) - soweit so gut. M.E. muß man da aber nicht unbedingt mit Setlength "herummachen", weil die Länge ja automatisch dort erfaßt und ggf. angepaßt, aktualisiert wird. Setlength benutzte ich bisher immer nur für (logischerweise dynamische) Arrays. In Turbo-Pascal waren auch schon Strings verminderter Länger verfüg-/deklarierbar, und damals gab es schließlich auch noch kein Setlength.
Wo wird nun aber die zusätzliche Information der maximalen Stringlänge gespeichert? Deklariert wird sie ja zur Entwurfszeit, aber wie gelangt sie in das Compilat, wie werden Überläufe bei Überschreiten der deklarierten Arraylänge erkannt und abgefangen (vermutlich Exceptions)?
|
|
jaenicke
      
Beiträge: 19339
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 15.08.12 14:46
Für diesen Beitrag haben gedankt: Delphi-Laie
|
|
|