![]() |
Problem mit #0 im String
Hi DP'ler,
ein kleines Problem: In edit1 steht Hex (z.B. 0C4B3A). In edit2 soll nacher der Text als solches stehen. Problem: Sobald in edit1 eine "00" (Beispiel: 0C54003A übrig bleibt nur oC54) auftaucht geht der Rest des Strings bei der Zuweisung zu edit2 verloren. Da edit2 aber nur ein "Zwischenspeicher" für den String ist darf das keinesfalls passieren. Hat jemand eine Idee? (INVHEXB ist eine Funktion von mir und funktioniert einwandfrei)
Delphi-Quellcode:
Danke im Vorraus!
b:=edit1.text;
a:=''; while length(b)>1 do Begin t:=INVHEXB(b[1]+b[2]); a:=a+chr(t); delete(b,1,2); end; edit2.Text:=a; |
Re: Problem mit #0 im String
Moin, Moin.
Zitat:
|
Re: Problem mit #0 im String
Tschaaa ... was soll man dazu sagen.
Sobald du eine binäre 0 im String hast, ist für die meisten Delphi-String-Routinen (und imho 99% aller anderen Sprachen + Windows) der String beendet. Das ist so eine Art Naturgesetz. Um die Null darzustellen musst du dir irgendetwas einfallen lassen. //Edit: obiger Text wurde dem revidierten Wissenstand angepasst :) |
Re: Problem mit #0 im String
Du solltest deine InvHexB so umschreiben, dass sie für alle Steuerzeichen (0..31) eine Sonderbehandlung durchführt, sonst wirst du keinen Spass daran haben.
|
Re: Problem mit #0 im String
... und wie kommt #0 in das EditFeld hinein?
Bevor ich die Symptome kuriere, wäre es doch besser die Ursache zu beseitigen, oder? |
Re: Problem mit #0 im String
Zitat:
Delphi-Quellcode:
String ist in Delphi durchaus in der Lage, auch #0 aufzunehmen, ohne die Länge zu kürzen. Nur Edit.Text ist wohl am Ende ein PChar, das dann bei der Anzeige tatsächlich abgeschnitten wird.
s := '1234'#0'6789';
Edit1.Text := s; // Anzeige 1234 ShowMessage(IntToStr(Length(s))); // 9! |
Re: Problem mit #0 im String
Wie? Du benutzt Edit2 nur als Zwischenspeicher?
@Chaosben Die Delphi-Strings haben ja gerade die Besonderheit sich nicht an einer #0 zu stören. Solange man auch nur mit DelphiStrings arbeitet ist das auch kein Problem. Nur die Übergabe zu dem von Windows verwalteten Edit erfolgt über PChar. Und erst da wird der String gekürzt. |
Re: Problem mit #0 im String
Ja, ok ... das Obige war nicht korrekt.
Strings können auch 0-Zeichen enthalten. Die Einschränkung ist eben nur, das 90% der String-Routinen hintenrum auf PChars basieren und deswegen mit 0-Zeichen nichts anfangen können. Und in diesem Fall gehts nicht, weil der Text eines Fenster/Edits per PChar gesetzt wird. |
Re: Problem mit #0 im String
Hi,
ich wollte hier keine Diskussion anfangen warum ich das so oder so mache! Hier nocheinmal eine kurze Erläuterung zur Problematik: Beispiel: ich muss den als Hex-Code voliegenden String zu einem Gerät binär übertragen (bei uns sind das Rundsteuerempfänger). Hex als char 30313233 -->'0123' das kann ich ohne weiteres übernehmen, kommt ja keine absolute 0 drin vor. Sobald ich 30310033 übertragen will krieg ich nur noch 3031, weil ja plötzlich im zu sendenden String eine '0' steht. '01'#0'2' Dass da Nullen vorkommen ist ein 'Naturgesetz' und nicht umgehbar! Das Übertragungsprotokoll kann ich auch nicht ändern! Wie machen das eigentlich die "C" Freaks? Ich habe die Edit-felder gegen 'normale' Strings ausgetauscht jetzt funktioniert das alles. Was mich stört ist: Wieso wird der String in tedit (tedit.text ist nichts anderes als ein String) anders behandelt als ein normaler String. Das ist doch Sch.... oder? Für alle die immer alles besser wissen: Die edit-Felder hab ich nur benutzt um zu sehen was passiert. Da das Ganze mit einer hohen Dynamik abläuft kommt der Debugger nicht in Frage. Hab mir halt auf diese Art beholfen. Vielen Dank für alle konstruktiven Beiträge! |
Re: Problem mit #0 im String
Zitat:
Zur Anzeige musst Du die Daten aber aufbereiten, also Zeichen 0-31 und 127 ersetzen (Parser). Den TEdit.Text wurde zwar in Delphi als String implementiert, ist aber eigentlich ein PChar (das eben keine #0 als Datenbestandteil aufnehmen kann). Das kann mit dem Standard TEdit auch nicht geändert werden, ist ja ein Windows-Objekt. Der einfachste Weg wäre, zur Datenspeicherung/Übermittlung Deine funktionierende Lösung und zur Anzeige den String aufbereiten. #0 = '<NUL>' ... #127 = '<ESC>' |
Re: Problem mit #0 im String
Das ist mal wieder ein typischer Anwendungsfall von 'Trenne Funktion und Darstellung'.
Die Funktion (hier: HEX->binär) funktioniert, mur für die Darstellung muss man eine andere Form wählen (z.B. wie Satty67 es vorgeschlagen hat). Falsch im Sinne des o.g. Paradigmas ist es, ein Darstellungselement (Edit2) als Funktionselement zu verwenden (Zwischenspeicher). |
Re: Problem mit #0 im String
Hi alzaimar,
Zitat:
Ich finde es halt schade, dass an dieser Stelle plötzlich die Philosophie (interne Darstellung von Variablen) einfach gewechselt wird. Ich bin davon ausgegangen, dass in Object pascal, alle Strings auch als "Delphi Strings" behandelt werden. Wer kommt denn auf die Idee, dass da plötzlich mit "0" terminierten Strings operiert wird. Das hat nichts mit Darstellungs oder Funktionselementen zu tun sondern mit der Konsequenz mit der eine Programmiersprache realisiert wird. Viele Grüsse |
Re: Problem mit #0 im String
Zitat:
|
Re: Problem mit #0 im String
Zitat:
Delphi übergibt an das Windows-Element evtl. sogar ein '1234'#0'6789'#0#0. Nur schneiden Windows Funktion den String vor seiner Sichtbarkeit ab. Ich bin sogar relativ sicher, dass Du in keiner Programmiersprache ein #0 in einem Windows-Edit sichtbar machen kannst. |
Re: Problem mit #0 im String
Hi,
Bernhard Geyer schrieb: Zitat:
Was mich stört ist weniger, dass man die "0" nicht sieht, (damit hab ich gerechnet) Mich stört, dass wenn ich edit1.text einen String zuweise der eine "0" enthält entweder die Setter Methode oder die Getter Methode den Rest abschneidet. Täusch ich mich oder ist das Object Pascal? Oder existiert edit1.text als String überhaupt nicht? Das heisst wird das direkt dem Windows Steuerelement zugewiesen und von da auch wieder geholt? Naja eine einfache Lösung hab ich jetzt ich stelle die Dinge halt in Hex dar. Vielen Dank! |
Re: Problem mit #0 im String
Ist aus der Vererbungshierarchie ersichtlich -> TWinControl
|
Re: Problem mit #0 im String
Zitat:
Aber auch wenn es ein Wrapper um KDE oder MacOS-Controls wäre, würde zu 99,9% das gleiche passieren. |
Re: Problem mit #0 im String
Eigentlich ist das Thema hier, die aus C bekannten Null terminierten Strings.
Das #0 Zeichen gibt das Ende des Strings an. Bei Pascalstrings steht die Länge des Strings vor dem ersten Zeichen im Speicher. Da Windows in C geschrieben ist, kommt das #0 zum Tragen bei der Anzeige. Delphi hat C kompatible Strings. Diese haben wie Pascal die Länge vor dem ersten Zeichen gespeichert und Terminieren noch zusätzlich den String mit #0. Daher kann die Windows API so Klasse angesprochen werden. |
Re: Problem mit #0 im String
Gibt es eine fertige C-Escape Funktion? Also eine Funktion die automatisch alles was in C-Escaped werden muss in einem PChar mit vernünftigen Escape Zeichen umwandelt?
'c:\dummesBeispiel\' -> 'c:\\dummesBeispiel\\' 'Meintext'#9'deintext' -> 'Meintext\tdeintext' #0 -> '\0' &c. |
Re: Problem mit #0 im String
Das würde dir auch nicht helfen, da das nur die Darstellung für den Compiler ist, und nicht die interne binäre Speicherung.
|
Re: Problem mit #0 im String
Stimmt ja.
gibt es keinen offiziellen standard wie man 0 in C Strings verpackt? Funktioniert '^A' ? |
Re: Problem mit #0 im String
Steuerzeichen sind Steuerzeichen. Selbst WENN #0 einen String nicht abschneiden würde, gäbe es kein darstellbares Zeichen dafür, wie auch für die meisten der unteren ASCII Zeichen. Sie sind eben nicht dafür gedacht, waren es auch nie und nirgends. End of Story.
Daher ist es auch seit Anbeginn aller Tage ein no-go Binärdaten in Strings zu halten. Dafür gibt es Arrays und Streams. |
Re: Problem mit #0 im String
Zitat:
|
Re: Problem mit #0 im String
Zur Visualisierung kann man sich ja auch schnell was basteln:
Delphi-Quellcode:
Bei Bedarf auch #32 als <SPACE> ...€: Done
function VisualizeASCII(Text : String; SpaceToo : Boolean) : String;
const ASCII_Codes : array[#0..#31] of String = ( '<NUL>', '<SOH>', '<STX>', '<ETX>', '<EOT>', '<ENQ>', '<ACK>', '<BEL>', '<BS>', '<TAB>', '<LF>', '<VT>', '<FF>', '<CR>', '<SO>', '<SI>', '<DLE>', '<DC1>', '<DC2>', '<DC3>', '<DC4>', '<NAK>', '<SYN>', '<ETB>', '<CAN>', '[i]', '<SUB>', '<ESC>', '<FS>', '<GS>', '<RS>','<US>'); DEL_Code = '<DEL>'; SPACE_Code = '<SPACE>'; var i : Integer; begin Result := ''; for i := 1 to Length(Text) do case Text[i] of #0..#31 : Result := Result + ASCII_Codes[Text[i]]; #32 : if SpaceToo then Result := Result + SPACE_Code else Result := Result + ' '; #127 : Result := Result + DEL_Code; else Result := Result + Text[i]; end; end; €2: 127 ist DEL nicht ESC :oops: |
Re: Problem mit #0 im String
Zitat:
Es wird nur zur Einfachheit das oft als String dargestellt. Gelegentlich werden auch andere Endzeichen genutzt. Aber das kommt auf das Protokoll an. |
Re: Problem mit #0 im String
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:04 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-2025 by Thomas Breitkreuz