Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Windows, Stream und String hin her convert fehler (https://www.delphipraxis.net/202051-windows-stream-und-string-hin-her-convert-fehler.html)

KodeZwerg 23. Sep 2019 12:35

Windows, Stream und String hin her convert fehler
 
Hallo, habe ein kleines Umwandlungsproblem und finde einfach nicht meinen Fehler.... grrrr
Einen String in einen Stream zu verwandeln scheint gut zu klappen,
die Rückumwandlung hingegen klappt nur manchmal korrekt, ich weiß nur nicht warum *heul*

Hier meine Versuche: (alles kommentiert damit man weiß warum ich was an welcher stelle mache)

Im Formular sind folgende Dinge existent:
Eine Memo, Edit und Knopf Komponente.
Delphi-Quellcode:
// pump text in einen stream
// diese methode scheint gut zu arbeiten
function TKlasse.StringToStream ( const InputString: String; var ResultStream: TMemoryStream ): Boolean;
var
  i: Integer;
begin
// falls was schiefgeht, erstmal falsen
  Result := False;
// wenn nix reinkommt, muss auch nix rauskommen
  if (Length(InputString) <= 0) = not False then
    Exit;
// falls stream inexistent ist, einen erstellen, ansonsten auf null position stellen
  if (ResultStream = NIL) = not False then
    ResultStream := TMemoryStream.Create
    else
    ResultStream.Position := 0;
  try
// stream beschreiben
    i := ResultStream.Write(InputString[1], Length(InputString));
  finally
// entweder haben wir es geschafft, oder auch nicht :-)
    if (i = Length(InputString)) = not false then
      Result := not False
      else
      Result := False
  end;
end;

// hol text aus einem stream
// hier steckt irgendwo ein fehler den ich nicht finde oder meine vorgehensweise ist falsch
function TKlasse.StreamToString ( const InputStream: TMemoryStream; var ResultString: String ): Boolean;
var
  Buffer: PChar; // (ist ein PWideChar bei D2010)
begin
// falls was schiefgeht, erstmal falsen
  Result := False;
// wenn stream inexistent ist oder leer ist, mach nichts
  if ((InputStream <> NIL) and (InputStream.Size > 0)) = not False then
    begin
      try
// puffer speicher allozieren
        Buffer := StrAlloc(InputStream.Size +1);
// stream position auf null setzen
        InputStream.Position := 0;
// stream inhalt an puffer pointen
        InputStream.Read(Buffer^, InputStream.Size);
// stringlänge anpassen
        SetLength(ResultString, SizeOf(Buffer));
// puffer in string kopieren
        ResultString := Copy(Buffer, 1, InputStream.Size);

// test ausgabe bevor speicher bereinigt ist
        MemoBox.Lines.Add('Buffer: ' + Buffer);
        MemoBox.Lines.Add('Result: ' + ResultString);

// puffer speicher freigeben
        StrDispose(Buffer);
      finally
// entweder haben wir es geschafft, oder auch nicht :-)
        if (Length(ResultString) = InputStream.Size) = not false then
          Result := not False
          else
          Result := False
      end;
    end;
end;

// hier meine Test-Methode die beides auf einmal verwendet....
procedure TKlasse.KnopfClick(Sender: TObject);
var
  tmp: TMemoryStream;
  s: String;
begin
  MemoBox.Lines.Add('Converting "' + EditZeile.Text + '" to stream');
  try
    if (StringToStream( EditZeile.Text, tmp ) = not False) = not False then
      if (StreamToString( tmp, s ) = not False) = not False then
        MemoBox.Lines.Add(s);
  finally
    tmp.Free;
  end;
end;

DeddyH 23. Sep 2019 12:46

AW: Windows, Stream und String hin her convert fehler
 
Solch eine innovative Boolean-Behandlung habe ich noch nie gesehen :shock:. Davon abgesehen: lass Dir doch SizeOf(Buffer) einmal ausgeben.

Schokohase 23. Sep 2019 12:48

AW: Windows, Stream und String hin her convert fehler
 
Schau mal in die Doku bei Delphi-Referenz durchsuchenTStreamReader und Delphi-Referenz durchsuchenTStreamWriter.

KodeZwerg 23. Sep 2019 13:14

AW: Windows, Stream und String hin her convert fehler
 
Danke Schokohase, doku schaut gut aus, ich hoffe mein altes Delphi hat das auch verbaut.

@DeddyH, mir wurde hier oft genug gesagt das man nicht auf ein true testen solle sondern immer auf false, hab ich da was falsch verstanden?

DeddyH 23. Sep 2019 13:20

AW: Windows, Stream und String hin her convert fehler
 
Ja, hast Du falsch verstanden. Du sollst am besten gar nicht gegen true oder false prüfen.
Delphi-Quellcode:
// Schlecht
if Dingens = true
Delphi-Quellcode:
// Besser
if Dingens
Delphi-Quellcode:
// Schlecht
if Dingens = false
Delphi-Quellcode:
// Besser
if not Dingens

KodeZwerg 23. Sep 2019 13:32

AW: Windows, Stream und String hin her convert fehler
 
Zitat:

Zitat von DeddyH (Beitrag 1447538)
Ja, hast Du falsch verstanden.

Das werde ich mir zu Herzen nehmen, Danke dafür.
TStringStream schau ich mir auch mal an, falls ich mit dem TStreamReader/Writer nicht zurecht kommen sollte (sofern bei D2010 vorhanden). Dankeschön @Frühlingsrolle

freimatz 24. Sep 2019 11:29

AW: Windows, Stream und String hin her convert fehler
 
Zitat:

Zitat von KodeZwerg (Beitrag 1447526)
Hallo, habe ein kleines Umwandlungsproblem und finde einfach nicht meinen Fehler.... grrrr
Einen String in einen Stream zu verwandeln scheint gut zu klappen,
die Rückumwandlung hingegen klappt nur manchmal korrekt, ich weiß nur nicht warum *heul*

1. Was ist der Fehler? Bitte konkreter. Was ist manchmal? Hängt das von ein Eingabedaten ab oder von Stand des Mondes? :wink:
2. Schon mal mit debuggen versucht? SCNR

Neutral General 24. Sep 2019 12:08

AW: Windows, Stream und String hin her convert fehler
 
Der Fehler liegt hier:
Delphi-Quellcode:
i := ResultStream.Write(InputString[1], Length(InputString));

Ein Char ist 2 Byte groß, daher ist ein String der Länge X = X * 2 (SizeOf(Char)) Bytes groß:
Delphi-Quellcode:
i := ResultStream.Write(InputString[1], Length(InputString) * SizeOf(Char));
Deine Abfragen auf die Stream/String längen musst du dann natürlich auch anpassen:

Delphi-Quellcode:
if (i = Length(InputString)) = not false then

und
Delphi-Quellcode:
if (Length(ResultString) = InputStream.Size) = not false then

KodeZwerg 24. Sep 2019 12:42

AW: Windows, Stream und String hin her convert fehler
 
Nach vielem hin und her probieren, streamreader/writer ist doch nicht das was ich benötige, der scheint mit dateien was am hut zu haben (habe mich aber nicht tiefer damit beschäftigt, geb ich zu!). ich arbeite hier nicht mit dateien sondern nur mit einem internen stream der dann übers netzwerk versendet werden soll.
(anfangs nur strings, später, wenn ich verstanden habe wie das ganze funktioniert auch mit binären krams)

Zitat:

Zitat von freimatz (Beitrag 1447681)
1. Was ist der Fehler? Bitte konkreter. Was ist manchmal? Hängt das von ein Eingabedaten ab oder von Stand des Mondes? :wink:
2. Schon mal mit debuggen versucht? SCNR

Debuggen fällt mir total schwer, da blick ich noch nicht durch, habe mal mit breakpoints rumprobiert aber bin nicht wirklich schlauer dadurch geworden.
Der Fehler ist, das wenn ich den Test starte, mit einem langen string "Die ist ein Beispiel String der Konvertiert werden soll" starte,
klappt es.
Ich verändere dann das Edit Feld auf, sagen wir mal "1", konvertierung klappt nicht, je mehr Zeichen ich dann ranhänge, umso interessantere ergebnisse werden geliefert (aus "123" wird mal "1" oder "12"....)

Zitat:

Zitat von Neutral General (Beitrag 1447685)
Ein Char ist 2 Byte groß, daher ist ein String der Länge X = X * 2 (SizeOf(Char)) Bytes groß:

das ergibt sinn und ich verstehe es, werd ich freudig heut abend testen *daumen drück* & vielen dank schonmal!!

Schokohase 24. Sep 2019 12:53

AW: Windows, Stream und String hin her convert fehler
 
Du weißt, dass eine Datei ein Stream ist (ein
Delphi-Quellcode:
TFileStream
)? Insofern kann man einen
Delphi-Quellcode:
TStreamReader
auch auf einen Datei loslassen, aber eben auch auf jeden anderen Stream, solange es eben ein Stream ist.

Sonst hätten die die Klasse ja auch nicht als StreamReader bezeichnet, sondern als FileReader, wenn das Teil nur mit Dateien umgehen könnte.

Und es kommt bei Text in einem Stream IMMER auf die Kodierung (Encoding) an. Wenn das nicht passt, dann kommt nur Murks beim Lesen raus.

Und genau da hilft auf der
Delphi-Quellcode:
TStreamReader
/
Delphi-Quellcode:
TStreamWriter
.

freimatz 24. Sep 2019 13:48

AW: Windows, Stream und String hin her convert fehler
 
Zitat:

Zitat von KodeZwerg (Beitrag 1447690)
Debuggen fällt mir total schwer, da blick ich noch nicht durch, habe mal mit breakpoints rumprobiert aber bin nicht wirklich schlauer dadurch geworden.

Hilft so was vielleicht?
https://www.youtube.com/watch?v=Oyd0ksN8cRs

Wichtig ist es schon. Ohne Debuggen ist es so wie Autos reparieren ohne die Motorhaube zu öffnen.

Luckie 24. Sep 2019 14:09

AW: Windows, Stream und String hin her convert fehler
 
Breakpunkt setzen, mit Mauszeuger 0ber Variablec fahren und Wert ablesen. Oder mit F7 in Einzelschritten durchgehen. Was ist daran so schwer?

scrat1979 24. Sep 2019 20:18

AW: Windows, Stream und String hin her convert fehler
 
Ich habe mir dazu mal einen Streamhelper geschrieben, funktioniert bislang problemlos...

Delphi-Quellcode:
[...}
type
  TStreamHelper = class helper for TStream
  public
    procedure ReadString(var Target : string);
    procedure WriteString (const s: string);
end;

[...]

procedure TStreamHelper.ReadString(var Target: String);
var
  len : Integer;
begin
  ReadBuffer(len, SizeOf(len));
  SetLength(Target, len);
  if (len > 0) then
    ReadBuffer(Target[1], len * SizeOf(Char));
end;


procedure TStreamHelper.WriteString (const s: string);
var
  len : Integer;
begin
  len := Length(s);
  WriteBuffer(len, SizeOf(len));
  if (len > 0) then
    WriteBuffer(s[1], len * SizeOf(Char));
end;

p80286 24. Sep 2019 20:21

AW: Windows, Stream und String hin her convert fehler
 
Zitat:

Zitat von Neutral General (Beitrag 1447685)

Ein Char ist 2 Byte groß, daher ist ein String der Länge X = X * 2 (SizeOf(Char)) Bytes groß:

Sicher? ist es nicht eher
Delphi-Quellcode:
langByte=length(instring)*sizeof(char);
Ggf. muß noch an die abschließenden CRLF gedacht werden also
Delphi-Quellcode:
langByte=length(instring)*sizeof(char)+sizeof(linebreak);

Gruß
K-H

Schokohase 24. Sep 2019 21:16

AW: Windows, Stream und String hin her convert fehler
 
Wenn es um Text, Stream und Encoding geht dann liest man doch immer wieder Sachen die stark nach Schlangenöl riechen.

Nochmals zur Info:

Delphi-Referenz durchsuchenTStreamWriter und Delphi-Referenz durchsuchenTStreamReader sind extra und nur für den einzigen Zweck gebaut worden um Text in einen Stream zu schreiben und von dort wieder zu lesen. (Die sind nicht von ungefähr von der abstrakten Klasse
Delphi-Quellcode:
TTextWriter
bzw.
Delphi-Quellcode:
TTextReader
abgeleitet)

Man gibt den Stream und das gewünschte Encoding an und kann Schreiben bis der Stream aus allen Nähten platzt. Das Lesen geht analog (Stream, Encoding) und Lesen bis der Arzt kommt.

Zitat:

Zitat von p80286 (Beitrag 1447752)
Ggf. muß noch an die abschließenden CRLF gedacht werden also
Delphi-Quellcode:
langByte=length(instring)*sizeof(char)+sizeof(linebreak);

Da fröstelt es mich doch ganz doll ...

p80286 24. Sep 2019 22:09

AW: Windows, Stream und String hin her convert fehler
 
war da nicht vor nicht so langer Zeit jemand, der mit
Delphi-Quellcode:
readln
gelesen hat, und sich dann gewundert hat, das nach dem zurückschreiben (nicht mit
Delphi-Quellcode:
writeln
) der Text etwas unleserlich war?

Gruß
K-H

KodeZwerg 25. Sep 2019 07:14

AW: Windows, Stream und String hin her convert fehler - (für mich gelöst, Danke!)
 
Danke für den Hinweis mit SizeOf(Char) !

Das funktioniert bei mir genau so wie ich es mir gewünscht habe ohne das ich auf etwas anderes umsteigen musste.
Tschuldigung, encoding, CRLF usw ist bei mir nicht so tragend/entscheidend.
String vom Edit sollte rein, Stream mit dem sollte raus und rückwärtsrum genauso.

Nach anpassung (Danke nochmal an Michael), klappts bei mir prima!

Delphi-Quellcode:
function TKlasse.StringToStream ( const InputString: String; var ResultStream: TMemoryStream ): Boolean;
var
  i: Integer;
begin
// falls was schiefgeht, erstmal falsen
  Result := False;
// wenn nix reinkommt, muss auch nix rauskommen
  if (Length(InputString) <= 0) then
    Exit;
// falls stream inexistent ist, einen erstellen, ansonsten auf null position stellen
  if (ResultStream = NIL) then
    ResultStream := TMemoryStream.Create
    else
    ResultStream.Position := 0;
// vor dem try den zähler auf null setzen damit compiler keine warnung wirft
  i := 0;
  try
// stream beschreiben
    i := ResultStream.Write(InputString[1], Length(InputString) * SizeOf(Char));
  finally
// entweder haben wir es geschafft, oder auch nicht :-)
    if (i = Length(InputString) * SizeOf(Char)) then
      Result := not False
      else
      Result := False
  end;
end;

function TKlasse.StreamToString ( const InputStream: TMemoryStream; var ResultString: String ): Boolean;
begin
// falls was schiefgeht, erstmal falsen
  Result := False;
// wenn stream inexistent oder leer ist, mach nichts
  if ((InputStream <> NIL) and (InputStream.Size > 0)) then
    begin
      try
// stream position auf null setzen
        InputStream.Position := 0;
// stringlänge anpassen
        SetLength(ResultString, InputStream.Size div SizeOf(Char));
// stream inhalt in string schreiben
        InputStream.Read(ResultString[1], InputStream.Size);
      finally
// entweder haben wir es geschafft, oder auch nicht :-)
        if (Length(ResultString) = InputStream.Size div SizeOf(Char)) then
          Result := not False
          else
          Result := False
      end;
    end;
end;

procedure TKlasse.btnKnopfClick(Sender: TObject);
var
  tmp: TMemoryStream;
  s: String;
begin
  Memo.Lines.Add('Converting "' + Edit.Text + '" to stream');
  try
    if (StringToStream( Edit.Text, tmp )) then
      if (StreamToString( tmp, s )) then
        Memo.Lines.Add(s);
  finally
    s := '';
    tmp.Free;
  end;
end;

Schokohase 25. Sep 2019 07:50

AW: Windows, Stream und String hin her convert fehler - (für mich gelöst, Danke!)
 
Zitat:

Zitat von KodeZwerg (Beitrag 1447797)
Tschuldigung, encoding, CRLF usw ist bei mir nicht so tragend/entscheidend.
String vom Edit sollte rein, Stream mit dem sollte raus und rückwärtsrum genauso.

Genau das sagt man sich bei Emba auch immer wieder. Hauptsache es kompiliert, dann ist es fertig zum Verkaufen.

Und das mit dieser gesonderten Betrachtung von CRLF (so wie hier in diesem Thread beschreiben) ist eher ein Indiz von "Ich habe überhaupt gar nichts verstanden" und man sollte den Worten eher keine Beachtung schenken.

Wenn es dich irgendwann dann doch treffen sollte, dann frag einfach nochmal nach, wie man es denn wirklich machen sollte (zudem der Code auch noch kürzer wird).

TiGü 25. Sep 2019 07:54

AW: Windows, Stream und String hin her convert fehler
 
Das
Delphi-Quellcode:
        if ... then
          Result := not False
          else
          Result := False
verursacht Flimmern vor meinen Augen!

Schokohase 25. Sep 2019 08:11

AW: Windows, Stream und String hin her convert fehler
 
Zitat:

Zitat von TiGü (Beitrag 1447801)
Das
Delphi-Quellcode:
        if ... then
          Result := not False
          else
          Result := False
verursacht Flimmern vor meinen Augen!

Über solche Kinkerlitzchen rege ich mich schon nicht mehr auf.

Aber auch dieser Code verrät so einiges ... und es drängt sich die Frage auf, warum daraus nicht einfach ein
Delphi-Quellcode:
Result := ...;
gemacht wird.

Wahrscheinlich viel zu kurz und viel zu wenig verschwurbelt.

KodeZwerg 25. Sep 2019 11:03

AW: Windows, Stream und String hin her convert fehler - (für mich gelöst, Danke!)
 
Zitat:

Zitat von Schokohase (Beitrag 1447800)
Und das mit dieser gesonderten Betrachtung von CRLF (so wie hier in diesem Thread beschreiben) ist eher ein Indiz von "Ich habe überhaupt gar nichts verstanden" und man sollte den Worten eher keine Beachtung schenken.

Wenn es dich irgendwann dann doch treffen sollte, dann frag einfach nochmal nach, wie man es denn wirklich machen sollte (zudem der Code auch noch kürzer wird).

Das hätte man auch freundlicher Formulieren können oder ich versteh es gerade eher negativ.
Ich schrieb doch bereits das ich mich mit dem Reader/Writer nicht tiefer beschäftigt habe, ich wollte nur kurzfristig für mein (unentgeldlisches... oje.. wassn wort) Hobby-Ding an ein funktionierendes Resultat kommen, genau das habe ich damit erreicht.
Klar, kein Unicode oder wenn man komplette Romane damit abarbeiten würde = Fehler. Das habe ich bereits begriffen, echt jetzt.
Wenn ich mehr Zeit habe, die bei mir momentan sehr sehr knapp bemessen ist, spiele ich mit dem Reader/Writer rum um damit das gleiche zu erzielen mit dem Vorteil auch Unicode und Zeilenumbrüche oder sonstige Escape-Sequenzen korrekt zu interpretieren, doch dafür fehlt mir leider gerade einfach die Zeit.

Wie dem auch sei, ich nahm Deinen Vorschlag bereits dankend an und zu gegebener Zeit (steht in meiner ToDo-Liste) werde ich definitiv damit erlernen umzugehen. Reader und Writer ist ja vom Namen bereits aussagekräftig genug, nur habe ich mich bis jetzt nur auf binärer Ebene mit Streams beschäftigt.
(Ob der Code nun kürzer oder länger ist spielt in meinem Hobby eher eine untergeordnete Rolle, aber klar, kürzer klingt toller :P)

Rollo62 25. Sep 2019 11:05

AW: Windows, Stream und String hin her convert fehler
 
Zitat:

Zitat von Schokohase (Beitrag 1447804)
Wahrscheinlich viel zu kurz und viel zu wenig verschwurbelt.

Security by obfuscation :stupid:

p80286 25. Sep 2019 12:07

AW: Windows, Stream und String hin her convert fehler
 
Delphi-Quellcode:
function TKlasse.StringToStream ( const InputString: String; var ResultStream: TMemoryStream ): Boolean;
var
  i: Integer;
begin
// falls was schiefgeht, erstmal falsen
  Result := False;
  if (Length(InputString) >0) then
  begin
  // falls stream inexistent ist, einen erstellen, ansonsten auf null position stellen
    if (ResultStream = NIL) then
      ResultStream := TMemoryStream.Create
    else
      ResultStream.Position := 0;
    i := 0;
    try
  // stream beschreiben
      i := ResultStream.Write(InputString[1], Length(InputString) * SizeOf(Char));
    finally
  // entweder haben wir es geschafft, oder auch nicht :-)
      Result:= (i = Length(InputString) * SizeOf(Char));
    end;
  end;
end;
Wahrscheinlich geht's besser....

Gruß
K-H

DeddyH 25. Sep 2019 12:07

AW: Windows, Stream und String hin her convert fehler
 
Was die anderen meinen: man kann die Zuweisung eleganter (und damit auch lesbarer) schreiben.
Delphi-Quellcode:
if Bedingung then
  Result := true
else
  Result := false;
Noch besser:
Delphi-Quellcode:
// Einzeiler
Result := Bedingung;
Somit muss sich niemand wegen doppelter Verneinung das Hirn verrenken ;)

Rollo62 25. Sep 2019 14:55

AW: Windows, Stream und String hin her convert fehler
 
Zitat:

Zitat von DeddyH (Beitrag 1447839)
Delphi-Quellcode:
if Bedingung then
  Result := true
else
  Result := false;

Ok, ich muss zugeben das mache ich auch manchmal so. :oops:

Denn einen Vortail hat es beim Debuggen,
- schnell drübersteppen, und man sieht direkt was die Bedingug war.
- oder mal eben eine Breakpoint draufsetzen.

freimatz 25. Sep 2019 16:08

AW: Windows, Stream und String hin her convert fehler
 
Dafür gibt es bedingte Breakpoints

Rollo62 25. Sep 2019 16:35

AW: Windows, Stream und String hin her convert fehler
 
Ja natürlich, ist aber etwas umständlicher :stupid:

Kommt auf den Anwendungsfall an, wenn ich Breakpoints schnell ein/ausschalten möchte,
um z.B. Events von externer Hardware zu debuggen, finde ich das ganz sinnvoll.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:23 Uhr.

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