![]() |
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; |
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.
|
AW: Windows, Stream und String hin her convert fehler
|
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? |
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 |
AW: Windows, Stream und String hin her convert fehler
Zitat:
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 |
AW: Windows, Stream und String hin her convert fehler
Zitat:
2. Schon mal mit debuggen versucht? SCNR |
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:
Deine Abfragen auf die Stream/String längen musst du dann natürlich auch anpassen:
i := ResultStream.Write(InputString[1], Length(InputString) * SizeOf(Char));
Delphi-Quellcode:
if (i = Length(InputString)) = not false then
und
Delphi-Quellcode:
if (Length(ResultString) = InputStream.Size) = not false then
|
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:
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:
|
AW: Windows, Stream und String hin her convert fehler
Du weißt, dass eine Datei ein Stream ist (ein
Delphi-Quellcode:
)? Insofern kann man einen
TFileStream
Delphi-Quellcode:
auch auf einen Datei loslassen, aber eben auch auf jeden anderen Stream, solange es eben ein Stream ist.
TStreamReader
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
|
AW: Windows, Stream und String hin her convert fehler
Zitat:
![]() Wichtig ist es schon. Ohne Debuggen ist es so wie Autos reparieren ohne die Motorhaube zu öffnen. |
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?
|
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; |
AW: Windows, Stream und String hin her convert fehler
Zitat:
Delphi-Quellcode:
Ggf. muß noch an die abschließenden CRLF gedacht werden also
langByte=length(instring)*sizeof(char);
Delphi-Quellcode:
langByte=length(instring)*sizeof(char)+sizeof(linebreak);
Gruß K-H |
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-Quellcode:
bzw.
TTextWriter
Delphi-Quellcode:
abgeleitet)
TTextReader
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:
|
AW: Windows, Stream und String hin her convert fehler
war da nicht vor nicht so langer Zeit jemand, der mit
Delphi-Quellcode:
gelesen hat, und sich dann gewundert hat, das nach dem zurückschreiben (nicht mit
readln
Delphi-Quellcode:
) der Text etwas unleserlich war?
writeln
Gruß K-H |
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; |
AW: Windows, Stream und String hin her convert fehler - (für mich gelöst, Danke!)
Zitat:
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). |
AW: Windows, Stream und String hin her convert fehler
Das
Delphi-Quellcode:
verursacht Flimmern vor meinen Augen!
if ... then
Result := not False else Result := False |
AW: Windows, Stream und String hin her convert fehler
Zitat:
Aber auch dieser Code verrät so einiges ... und es drängt sich die Frage auf, warum daraus nicht einfach ein
Delphi-Quellcode:
gemacht wird.
Result := ...;
Wahrscheinlich viel zu kurz und viel zu wenig verschwurbelt. |
AW: Windows, Stream und String hin her convert fehler - (für mich gelöst, Danke!)
Zitat:
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) |
AW: Windows, Stream und String hin her convert fehler
Zitat:
|
AW: Windows, Stream und String hin her convert fehler
Delphi-Quellcode:
Wahrscheinlich geht's besser....
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; Gruß K-H |
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:
Noch besser:
if Bedingung then
Result := true else Result := false;
Delphi-Quellcode:
Somit muss sich niemand wegen doppelter Verneinung das Hirn verrenken ;)
// Einzeiler
Result := Bedingung; |
AW: Windows, Stream und String hin her convert fehler
Zitat:
Denn einen Vortail hat es beim Debuggen, - schnell drübersteppen, und man sieht direkt was die Bedingug war. - oder mal eben eine Breakpoint draufsetzen. |
AW: Windows, Stream und String hin her convert fehler
Dafür gibt es bedingte Breakpoints
|
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 22:03 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz