![]() |
Datentypen von String zu Byte und wieder zurück
Hi,
ich hoffe ihr könnt mir helfen. Also folgendes, ich bekomme über eine Schnittstelle zwei Strings. Die sehen zum Beispiel so aus: 1. Datensatz: 003F800 2. Datensatz: 001FC00 Die einzelnen Zeichen in dem String muss ich nun so umformen, das ich die hex Zeichen im String zu Binary umforme: 1. Datensatz: 0000|0000|0011|1111|1000|0000|0000 2. Datensatz: 0000|0000|0001|1111|1100|0000|0000 Diese beiden Datensätze muss ich dann zu einem zusammenfügen. Dazu nehme ich das erste Zeichen von Datensatz 2 dann das erste von Datensatz 1 dann das zweite von Datensatz 2 usw. 1 u. 2 zusammen: 0000|0000|0000|0000|0000|0111|1111|1111|1110|0000| 0000|0000|0000|0000 Und dann wieder umwandeln in einen String mit den Hex Werten 1 u. 2 zusammen: 0|0|0|0|0|7|F|F|E|0|0|0|0|0 Ich hoffe ich habe das verständlich erklärt. Im Voaraus schonmal vielen Dank. |
AW: Datentypen von String zu Byte und wieder zurück
Wozu die zwischenzeitliche Umkonvertierung in Bits und wieder zurück?
Du nimmst doch eigentlich aus den beiden Strings (das sind keine Datensätze!) jeweils die Zeichen! Dazu stimmt Dein Beispiel nicht! Mein Beispiel: 1) 12345 2) ABCDE Ergebnis soll sein A1B2C3D4E5 richtig? Nur mal zusammengetippt:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var a,b,r : string; i : integer; begin a := '12345'; b := 'ABCDE'; r := ''; for i := 1 to 5 do r := r + b[i] + a[i]; ShowMessage(r); end; Ciao Stefan |
AW: Datentypen von String zu Byte und wieder zurück
Hi,
entschuldige meine falsche Ausdrucksweise :oops: Die "Sortierung" die du gemacht hast ist für mich nicht ausreichend. Wenn ich mein Beispiel nehme wird aus: 003F800 + 001FC00 = 000007FFE00000 und nicht: 003F800 + 001FC00 = 000013FFC80000 |
AW: Datentypen von String zu Byte und wieder zurück
Zitat:
Deine beiden Ausgangswerte haben je 2 Nullen vorn, Dein Ergebnis hat vorn 5 Nullen Dann kommt eine 1 und eine 3, warum wird da im Ergebnis 7? Ich verstehe immer noch nicht was Du da eigentlich machen willst! Ciao Stefan |
AW: Datentypen von String zu Byte und wieder zurück
Ich verstehe das so, daß du die beiden Hex-Strings bitweise verschachtelst. Folgende Funktion sollte das leisten:
Delphi-Quellcode:
function Convert(const A, B: string): string;
function Merge(CA, CB: Char): string; type TByteSet = set of 0..3; var BS: TByteSet; b1: Byte; b2: Byte; I: Integer; begin b1 := StrToInt('$' + CA); b2 := StrToInt('$' + CB); BS := []; for I := 0 to 3 do begin if I in TByteSet(b1) then begin Include(BS, 2*I); end; if I in TByteSet(b2) then begin Include(BS, 2*I + 1); end; end; Result := IntToHex(Byte(BS), 2); end; var I: Integer; begin Assert(Length(A) = Length(B), 'Strings müssen gleich lang sein!'); Result := ''; for I := 1 to Length(A) do begin Result := Result + Merge(A[I], B[I]); end; end; |
AW: Datentypen von String zu Byte und wieder zurück
Hallo Uwe,
deine Funktion ist genau das was ich gebraucht habe. Vielen Dank!!! Wenn ich zwei feste Strings in die Funktion eintrage kommt genau das Ergebniss welches ich mir erhofft habe. Die Strings die von der Schnittstelle kommen will er leider noch nicht verarbeiten... Da hab ich irgendwo noch nen Fehler... Aber den soll ich wohl noch finden. Nochmal vielen Dank!! |
AW: Datentypen von String zu Byte und wieder zurück
BS hat offiziell nur 4 Bit, aber irgendwer tut da 8 Bits rein .... so ganz Richtig kann das nicht sein. :zwinker:
Deine Beschreibung war in #1 nicht so gut. Für mich klang das auch so, als wenn du jeweils "ein Hex-Zeichen" mischen willst und nicht die einzelnen Bits. |
AW: Datentypen von String zu Byte und wieder zurück
Zitat:
Also wenn ich doppelt so viele Bit trinke, wie ich eigentlich vertrage, dann kommt es bei mir zu einem Überlauf... ;) |
AW: Datentypen von String zu Byte und wieder zurück
Ja, immer wieder spannend was man so alles in eine einfache Menge packen kann :-D.
Ich nehm mal an, dass das viele Delphianer nicht wissen und UR uns allen damit wieder einmal zeigen wollte, was Delphi so alles kann ;-). Schnell ist das aber nicht. Wenn viele Daten anfallen / Tempo eine Rolle spielt, dann kann man es auch so machen:
Delphi-Quellcode:
Das ist auf meiner Kiste über 16 Mal schneller und da die beiden Algos O(n) sind, ist das wohl auch auf langsameren und schnelleren Kisten so.
var merger : array[0..15,0..15] of string;
hti : array[ '0'..'F' ] of integer; function ConvertA(const A, B: string): string; var i : integer; begin Assert(Length(A) = Length(B), 'Strings müssen gleich lang sein!'); Result := ''; for i := 1 to length(A) do Result := Result + merger[hti[A[i]],hti[B[i]]]; end; |
AW: Datentypen von String zu Byte und wieder zurück
Zitat:
Delphi-Quellcode:
muss natürlich so deklariert sein:
TByteSet
Delphi-Quellcode:
Übrigens: Das funktioniert deshalb, weil Delphi immer ganze Bytes für Sets reserviert.
type
TByteSet = set of 0..7; Zitat:
Delphi-Quellcode:
deklarieren). Es ging mir hier aber im Wesentlichen darum, den beschriebenen Algorithmus möglichst exakt nachzubilden.
const
|
AW: Datentypen von String zu Byte und wieder zurück
Ja, Natürlich kann man nur auf ganze Bytes zugreifen und Delphi rundet immer auf.
Ein Boolean kennt auch 1x False und 255x True :stupid: Aber blöd wird es, wenn man die Bereichsprüfung mal aktiviert und dann der Typ zu klein deklariert ist. |
AW: Datentypen von String zu Byte und wieder zurück
Liste der Anhänge anzeigen (Anzahl: 1)
Das ist sogar noch witziger:
Delphi-Quellcode:
BreakPoint 1 wird 8x durchlaufen! BreakPoint 2 erwartungsgemäß nur 2x.
type
TSet = set of 0..3; procedure Main; var s: TSet; I: 0..3; begin s := [1,3]; for I in s do begin // <== BreakPoint 1 Writeln(I); // <== BreakPoint 2 end; end; // <== BreakPoint 3 Bei den Durchläufen vor dem ersten Writeln hat I nicht mal einen definierten Wert. |
AW: Datentypen von String zu Byte und wieder zurück
Leider bekomm ich es doch nicht ans laufen...
Wenn ich der Funktion feste Werte übergebe funktioniert sie wunderbar.
Code:
Wenn ich aber meine Buffer der Funktion übergebe kommt nichts aus ihr raus.
PBuf := Convert('00003FFFC000','00003FFFC000');
Code:
Könnt ihr mir sagen was ich da falsch mache?
BEGIN
PBuf1 := Copy(PBuf10,13,Length(PBuf10)-3); PBuf2 := Copy(PBuf20,13,Length(PBuf20)-3); if (length(PBuf1) = length(PBuf2)) then begin PBuf := Convert(PBuf1,PBuf2); PBufSend := PBuf; end; END; |
AW: Datentypen von String zu Byte und wieder zurück
Wie sind denn die PBuf.. deklariert und was sagt der Debugger?
|
AW: Datentypen von String zu Byte und wieder zurück
Ist alles als String deklariert
|
AW: Datentypen von String zu Byte und wieder zurück
Dann setze mal einen Haltepunkt und schau dir an was in den Strings, die du übergibst, drin steht.
|
AW: Datentypen von String zu Byte und wieder zurück
Zitat:
:glaskugel: Eventuell versuchst du ja auch nur die ersten 12 und die letzen 2 oder 3 Zeichen abzuschneiden? Dann ist das aber der falsche Befehl. |
AW: Datentypen von String zu Byte und wieder zurück
:? Ja das Stimmt.. Ich will von dem String die ersten 12 Zeichen wegschneiden und am Ende die letzten drei.
Ist es so besser?
Code:
BEGIN
Delete(PBuf10,0,12); Delete(PBuf20,0,12); Delete(PBuf10,length(PBuf10)-3,3); Delete(PBuf10,length(PBuf20)-3,3); if (length(PBuf10) = length(PBuf20)) then begin PBuf := Convert(PBuf10,PBuf20); PBufSend := PBuf; end; END; Es sind alle Buffer mit string deklariert. Die Strings sind alle 60 Zeichen lang. |
AW: Datentypen von String zu Byte und wieder zurück
Zitat:
|
AW: Datentypen von String zu Byte und wieder zurück
Delphi 2010 Windows 7
|
AW: Datentypen von String zu Byte und wieder zurück
Hallo Graw,
du weisst doch wie man in der IDE den Debugger nutzt? Du kannst damit bequem Zeile für Zeile durch dein Programm steppen und dabei beobachten wie sich die Werte deiner Variablen ändern und findest den/die Fehler in deinem Code so sicher sehr rasch. In deinem Fall überwache die Ausdrücke PBuf, PBuf10, PBuf20 und setze einen Breakpoint bei deiner ersten Zeile und lass es laufen :-). |
AW: Datentypen von String zu Byte und wieder zurück
Zitat:
Delphi-Quellcode:
Du kannst auch Copy verwenden:
Delete(PBuf10, 1, 12);
Delete(PBuf20, 1, 12); Delete(PBuf10, length(PBuf10) - 2, 3); Delete(PBuf20, length(PBuf20) - 2, 3); // In deinem Code veränderst du übrigens PBuf10!
Delphi-Quellcode:
Oder das Ganze gleich in eine eigene Funktion kapseln:
PBuf10 := Copy(PBuf10, 13, Length(PBuf10) - 15);
PBuf20 := Copy(PBuf20, 13, Length(PBuf20) - 15);
Delphi-Quellcode:
function ClipString(const Value: string; Head, Tail: Integer): string;
begin result := Copy(Value, Head + 1, Length(Value) - (Head + Tail)); end; PBuf10 := ClipString(PBuf10, 12, 3); PBuf20 := ClipString(PBuf20, 12, 3); |
AW: Datentypen von String zu Byte und wieder zurück
Delphi-Quellcode:
Edit: Habe übersehen, dass das schon oben steht.
PBuf1 := Copy(PBuf10,13,Length(PBuf10)-15);
|
AW: Datentypen von String zu Byte und wieder zurück
Warum nimmst du nicht einfach zwei Variablen, in denen du das erst mal zwischenspeicherst. Das macht den Code auch übersichtlicher.
|
AW: Datentypen von String zu Byte und wieder zurück
Hat nun doch alles geklappt. Hatte meine Strings nicht richtig geschnitten.
Vielen Dank. |
AW: Datentypen von String zu Byte und wieder zurück
Ein anderer Weg, mit reinem Assembler geht das natürlich noch kompakter:
Delphi-Quellcode:
function Rol(const AValue: LongWord; const ACount: Byte): LongWord; register;
asm mov cl, dl rol eax, cl end; function IntConvert(A, B: LongWord): Int64; var i: integer; begin Result := 0; for i := 0 to 31 do begin Result := Result shl 1; B := Rol(B, 1); Result := Result or (B and $00000001); Result := Result shl 1; A := Rol(A, 1); Result := Result or (A and $00000001); end; end; function Convert(const A, B: string): string; var aa, bb: LongWord; begin aa := StrToInt('$' + A); bb := StrToInt('$' + B); Result := IntToHex(IntConvert(aa, bb), 16); end; |
AW: Datentypen von String zu Byte und wieder zurück
Delphi-Quellcode:
:?:
for i := 0 to 31 do
begin Result := Result shl 1; B := B shl 1; Result := Result or (B shr 31); Result := Result shl 1; A := A shl 1; Result := Result or (A shr 31); end; |
AW: Datentypen von String zu Byte und wieder zurück
Beide verschieben die Bits nach links, aber shl schiebt nur 0-Bits von rechts nach.
12345678 shl 4 -> 23456780 12345678 rol 4 -> 23456781 |
AW: Datentypen von String zu Byte und wieder zurück
Wenn dann so:
Delphi-Quellcode:
for i := 0 to 31 do
begin Result := Result shl 1; Result := Result or (B shr 31); B := B shl 1; Result := Result shl 1; Result := Result or (A shr 31); A := A shl 1; end; |
AW: Datentypen von String zu Byte und wieder zurück
Doch, kann ich, aber :oops:
Delphi-Quellcode:
In diesem Fall wird das ja nur benutzt, um nacheinander jedes Bit auszulesen und in diesem Fall kann man einfach auf der anderen Seite auslesen, anstatt im Kreis zu schieben.
for i := 0 to 31 do
begin Result := Result shl 1; Result := Result or (B shr 31); B := B shl 1; Result := Result shl 1; Result := Result or (A shr 31); A := A shl 1; end; [edit] jupp [edit2]
Delphi-Quellcode:
for i := 31 downto 0 do
begin Result := Result shl 1; Result := Result or ((B shr i) and $1); Result := Result shl 1; Result := Result or ((A shr i) and $1); end;
Delphi-Quellcode:
?
for i := 31 downto 0 do
begin Result := Result shl 2; Result := Result or ((B shr (i-1)) and $1) // schiebt SHR bei -1 nach links? or ((A shr i) and $1); end; |
AW: Datentypen von String zu Byte und wieder zurück
Der zweite Operand ist ein Byte, welches zusätzlich maskiert ist.
Byte(-1) -> 255 (255 mod 32) -> 31 (Longword(a) shr -1) -> (a shr 15) Das funktioniert also nicht, abgesehen davon müsste die Maske für B $2 sein. |
AW: Datentypen von String zu Byte und wieder zurück
So kann es funktionieren und ist übersichtlich:
Delphi-Quellcode:
for i := 31 downto 0 do
begin Result := Result shl 1; Result := Result or ((B shr i) and $1); Result := Result shl 1; Result := Result or ((A shr i) and $1); end; |
AW: Datentypen von String zu Byte und wieder zurück
Richtig müsste es heißen: (Longword(a) shr -1) -> (a shr 31)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:27 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