![]() |
strtohex
Hi zusammen,
ich möchte eine Spielstand Datei als Hex ins Memo laden, nur bekomm ich die Umwandlung von String zu Hex nicht so wirklich gebacken. Ein Hex Editor zeigt mir zumindest andere Werte.
Delphi-Quellcode:
mal ein Auszug aus der Datei '...ÿ..ö.üÿæ.....'
function StringToHex(s:string) : string;
var t : integer; begin result := ' '; for t := 1 to length(s) do begin if t = length(s) then result := result + IntToHex(ord(s[t]),2) else result := result + IntToHex(ord(s[t]),2) + ' '; end; end; so zeigt es der Hex Editor an '0E 00 90 FF 00 00 F6 13 FC FF E6 11 10 00 00 00' und so mein Programm '2E 2E 2E FF 2E 2E F6 2E FC FF E6 2E 2E 2E 2E 2E' Was läuft da schief? |
Re: strtohex
Die Datei ist binär Codiert. Dann solltest Du sie mit TFileStream laden und nicht mit Strings arbeiten.
|
Re: strtohex
Hi,
dein Programm macht alles richtig dein fehler ist das du den "String" den der Hex-Editor dir wieder gegeben hat in deinem programm benutzt: Zitat:
Kurz gesagt kopiere den string nicht aus dem Hex-Editor sondern lade die datei in dein programm rein. MfG Carlo |
Re: strtohex
Für mich sieht es aus, als würdest du die Datei als String einlesen und die dann in Hex umwandeln.
Macht man das nicht mit einem FileStream, und liest Byte für Byte aus und wandelt den in Hex um? So denke ich mir das. (Es kann natürlich auch sein, das beides geht, aber an deinem gezeigten Code sehe ich kein Fehler)
Delphi-Quellcode:
ungetestet
var
fs:TFileStream; str : String //was am Ende Rauskommt i : Integer; b : Byte; begin fs := TFileStream.Create('Datei', fm_OpenRead); try For i := 0 to fs.Size do begin fs.ReadBuffer(b,sizeof (b)); //oder fs.ReadByte(b); <-- bin mir nichtt sicher str := Str + '|' + IntToHex(b,2); <-- '|' ist der Trenner end; finally fs.Free; end; end; [edit] Hmm... Zum 1. Mal kein roter Kasten... [/edit] |
Re: strtohex
Nunja, deine Funktion ist in Ordnung. Nur dein String ist einwenig nicht in Ordnung weil die punkte sind in Hex 0x2E, der HexEditor kann diese Zeichen einfach nicht darstellen.
Z.B.:
Delphi-Quellcode:
Siehst gleich das die anderen Bytes angezeigt werden.
showmessage(stringtohex('hi was geht?'#0#12#13#14#0'wieder ich!'));
|
Re: strtohex
Zitat:
[edit] Ich habs jetzt kapiert, was du meinst. Da stand wer auf meiner Internetleitung :mrgreen: [/edit] |
Re: strtohex
Ja sollte angezeigt werden warum auch nicht lol?
|
Re: strtohex
Zitat:
an sich sollte der hier gepostete Weg auf jeden Fall funktionieren. Wenn Du das so machst, solltest Du jedoch noch besser noch mit einem kleinen Puffer arbeiten. In diesem Fall liest Du jedes Byte einzeln in der Schleife ein, dass dauert und dauert und dauert. Viel schneller geht es, wenn Du gleich einen ganzen Haufen Bytes in ein Array liest und die dann in einem Rutsch bearbeitest.
Delphi-Quellcode:
Auch das mit dem String kann man noch effizienter machen, indem man hier für jedes Zeichen im Puffer (readBytes) einfach je 3 Byte (2 Byte Hex-Wert + 1 Byte Trenner) alloziert und dann direkt am richtigen Index einfügt.
var buffer: TByteDynArray;
readBytes: Integer; // wie gehabt! ... begin // 1024 Byte Puffer setLength(buffer, 1024); // wie gehabt! ... readBytes := fs.Readbuffer(buffer[0], length(buffer)); while readBytes > 0 do begin for i := 0 to readBytes - 1 do begin str := Str + '|' + IntToHex(buffer[i],2); <-- '|' ist der Trenner end; end; Gruß Der Unwissende [edit] Fehler korrigiert, muss natürlich read und nicht readBuffer sein! Danke @halinchen! [/edit] |
Re: strtohex
@Der_Unwissende: Schon klar, das meine Lösung nicht optimal ist. Wie immer :mrgreen:. Nein Spaß bei Seite. Sollte ja nur ein Anschauungsmaterial sein.
Allerdings nahm bei mir mal ReadBuffer bei einem älteren Projekt keine variablen Arrays an. Gleich nochmal testen und lernen :coder2: [edit] oh, sry. das war ja Carlo91 und war auch keine Frage... :wall: [/edit] @ReVenGer: Du sollst die Daten nicht aus dem Hex-Editor kopieren, sondern selber die Datei einlesen. Den sonst ist dort wo z.B #13 steht in deinem Programm ein Punkt. Sprich: Beide Programme arbeiten mit unterschiedlichem Ausgangsmaterial. |
Re: strtohex
ahhhhhhhhh.... *klick*
erstmal danke für die schnellen antworten! ich habe fälschlicherweise angenommen, das er das nur nicht anzeigen kann, aber den tatsächlichen wert übernimmt. super, dann kann ich ja auch gezielt nach bytes suchen und diese verändern. speichern sollte genau rückwärts erfolgen richtig? |
Re: strtohex
Zitat:
Bei meinem ersten Programm, dass da mal größere Dateien (> 100 MByte) öffnen musste war das dann der Unterschied zwischen 1 Minute Ladezeit und < 1 Sekunde. Waren dann noch ein zwei andere Stellen, wo ich das Speicherkopieren in Schleifen durch Move ersetzt habe, macht natürlich einiges aus! |
Re: strtohex
Ich hab da wohl noch nen denkfehler drin.
Delphi-Quellcode:
und aufgerufen wird es so
function StringToHex(str :string) : string;
var fs:TFileStream; i : Integer; b : Byte; begin fs := TFileStream.Create('test.gam', fmOpenRead); try For i := 0 to fs.Size do begin fs.ReadBuffer(b,sizeof (b)); //oder fs.ReadByte(b); <-- bin mir nichtt sicher str := Str + '|' + IntToHex(b,2); end; finally fs.Free; end; end;
Delphi-Quellcode:
label3.caption:=stringtohex(str);
war jetzt nur damit es schnell geht nen label. die datei die ich einlese hat nur 30kB. von daher nichts großes, deshalb habe ich mich auhc für die kleine variante entschieden. aber das programm erzeugt einen error. |
Re: strtohex
Delphi-Quellcode:
Allerdings solltest du dir bewusstsein, das es vielleicht besser ist, den Spielstand immer im Speicher zu haben (z.B als TMemoryStream). Den sonst musst du dich so blöd mit dem Trennstrich rumärgern.
function StringToHex : string;
var fs:TFileStream; i : Integer; b : Byte; begin result := ''; fs := TFileStream.Create('test.gam', fmOpenRead); try For i := 0 to fs.Size do begin fs.ReadBuffer(b,sizeof (b)); //oder fs.ReadByte(b); <-- bin mir nichtt sicher result := result + '|' + IntToHex(b,2); end; finally fs.Free; end; end; |
Re: strtohex
Delphi-Quellcode:
var
fs: TFileStream; lpBuffer: array of Byte; // temporär s: string; x: Integer; begin // entweder so, oder du ließt es in Blöcken aus und parst sie schon gleich ... fs := TFileStream.Create('c:\tmp.txt', fmOpenRead); try if (fs.Size > 0) then begin SetLength(lpBuffer, fs.Size); fs.Read(lpBuffer[0], fs.Size); end; finally fs.Free; end; // brauchst nicht - nur ausgabe s := ''; for x := Low(lpBuffer) to High(lpBuffer) do begin s := s + IntToHex(lpBuffer[x], 2) + ' '; end; ShowMessage(s); |
Re: strtohex
Bekomme immer die meldung 'incompatible types intger and string"
|
Re: strtohex
Zitat:
[edit] ich hab jeden Code ausprobiert. Bei mir gehen alle[/edit] |
Re: strtohex
bei der übergabe zum memo,label, etc.
wie rufst du denn die function auf? |
Re: strtohex
bei der übergabe zum memo,label, etc.
wie rufst du denn die function auf? |
Re: strtohex
Dann zeige uns doch einmal wie Du es jetzt hast?
So ist nur raten angesagt. Grüße Klaus |
Re: strtohex
jetzt hab ich nen streamread error.. ich bau das jetzt nochmal komplett um.
|
Re: strtohex
Delphi-Quellcode:
Wenn mir das jetzt nochmal einer erklären könnte habt ihr mich glücklich gemacht.
Procedure stringtohex;
var fs: TFileStream; lpBuffer: array of Byte; s: string; x: Integer; begin fs := TFileStream.Create('test.gam', fmOpenRead); try if (fs.Size > 0) then begin SetLength(lpBuffer, fs.Size); fs.Read(lpBuffer[0], fs.Size); end; s := ''; for x := Low(lpBuffer) to High(lpBuffer) do begin s := s + IntToHex(lpBuffer[x], 2) + ' '; end; Memo1.Lines.Add(s); finally fs.Free; end; end; [Error] Unit2.pas(71): Undeclared identifier: 'Memo1' [Error] Unit2.pas(71): Missing operator or semicolon [Fatal Error] Project1.dpr(6): Could not compile used unit 'Unit2.pas' Verstehe das nicht,warumdas mit showmessage geht, aber das memo nicht finden kann. |
Re: strtohex
Guten Morgen.
StrToHex() ist bei dir eine unabhängige Prozedur und keine Methode der Form. Das ist auch richtig so, aber du kannst aus dieser Prozedur nicht auf Eigenschaften der Form (z.B. Memo1) zugreifen. Alle Ein- und Ausgaben deiner Prozedur sollten über entsprechende Parameter gesteuert werden. Eine sinnvolle Signatur wäre:
Delphi-Quellcode:
Ein Aufruf könnte so aussehen: HexDump('C:\highscore.dat', Memo.Lines);
procedure HexDump(const fn: TFileName; s: TStrings);
Für die Konvertierung von Bytes in ihre Hex-Darstellung gibt es die Funktion BinToHex(). Grüße vom marabu |
Re: strtohex
danke erstmal für die antwort,
aber wenn ich es so aufrufe, bekomme ich den undeclared identifier opendialog1.
Delphi-Quellcode:
stringtohex(OpenDialog1.FileName, Memo1.Lines.add);
|
Re: strtohex
Vermutlich hast du an der Stelle, an der du den Aufruf von StrToHex() machst, keinen Zugriff auf OpenDialog1. Kannst du den Aufruf mal in seinem Kontext zeigen?
|
Re: strtohex
Ich hätte bei Assembler bleiben sollen :)
Delphi-Quellcode:
Procedure stringtohex(const fn: TFileName; sg: tStrings);
var fs: TFileStream; lpBuffer: array of Byte; x: Integer; s: string; begin fs := TFileStream.Create('test.gam', fmOpenRead); try if (fs.Size > 0) then begin SetLength(lpBuffer, fs.Size); fs.Read(lpBuffer[0], fs.Size); end; s := ''; for x := Low(lpBuffer) to High(lpBuffer) do begin s := s + IntToHex(lpBuffer[x], 2) + ' '; end; // showmessage(s); finally fs.Free; end; end; procedure TForm2.N3Click(Sender: TObject); begin opendialog1.execute; HexDump(OpenDialog.FileName, Memo.Lines); //showmessage(opendialog1.filename); //Pfad end; |
Re: strtohex
Delphi-Quellcode:
sollte es nicht openDialog1 heißen und nicht openDialog?
HexDump(OpenDialog1.FileName, Memo.Lines);
Grüße Klaus |
Re: strtohex
sorry, hatte ich hinterher korrigiert.
trotzdem sagt er mir undeclared identifier. ich versteh das nicht, in assembler konnte ich immer direkt auf sachen zugreifen, ohne umwege. |
Re: strtohex
Manchmal möchte man den OpenDialog abbrechen:
Delphi-Quellcode:
Freundliche Grüße
procedure TForm2.N3Click(Sender: TObject);
begin with OpenDialog1 do if Execute then StrToHex(FileName, Memo.Lines); end; |
Re: strtohex
Zitat:
|
Re: strtohex
Hallo,
ich vermute, dass die Komponente OpenDialog1 auf einer anderen Form als Form2 zu finden ist. Falls sich OpenDialog1 auf Form1 befindet, dann musst du deinen Quellcode so abändern:
Delphi-Quellcode:
Damit würde dann dein Code übersetzt, aber elegant ist das nicht. Da du aber noch schwer mit Delphi kämpfst, bringt es dir zumindest eine "schnelles" Erfolgserlebnis. Pascal und seine Nachkommen sind block-orientierte Sprachen und die Variablen haben einen Gültigkeitsbereich. Lies zu diesem Thema in der Online-Hilfe das Topic "Delphi Sprachreferenz | Syntaktische Elemente | Blöcke und Gültigkeitsbereich" und du findest bestimmt einen Einstieg.
procedure TForm2.N3Click(Sender: TObject);
begin with Form1.OpenDialog1 do if Execute then StrToHex(FileName, Memo.Lines); end; Grüße vom marabu |
Re: strtohex
also ich habe noch immer das problem mit udeclared identifier.
egal was ich mache, ob ich nen komplett neues projekt nehme (hatte vermutet das beim alten was verbogen war) oder ich in meiner source die sachen verändere, ich bekomme den stream nicht in mein memo. |
Re: strtohex
Häng doch bitte mal dein Projekt als Anhang an.
[edit] Oder, wenn es zu groß ist: Du sagtest, das es mit einem neuen Projekt auch nicht geht. Dann kannst du das anhängen [/edit] |
Re: strtohex
Liste der Anhänge anzeigen (Anzahl: 1)
Hier mal die Source.
Bin echt am verzweifeln, weil er ja den schowmessage dialog aufruft. nur das memo nicht |
Re: strtohex
Bei mir gehts. Es zeigt in einer MessageBox die Hex-Dinger an. Aber von einem Memo sehe ich weit und breit nichts.
Du musst schon irgentwo auf der Form ein Memo anlegen. Wenn ich eins auf die Form ziehe und dann das Programm starte gehts auch mit Memo. Im Übrigen:
Delphi-Quellcode:
Form2 muss mit davor wenns auf Form2 ist.
Form2.Memo1.Lines.Add(s)
|
Re: strtohex
Mal eine ganz dumme Frage, auf welcher Form soll denn das memo1 sein.
Habe keines gefunden. Grüße Klaus |
Re: strtohex
jetzt gehts bei mir auch :wall:
ich danke euch, hab vor lauter editieren und verändern komplett die übersicht verloren. oh man... es gibt tage da verliert man, und tage, da gewinnen die anderen... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:09 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