![]() |
Strings und Ansistrings, Nullterminiert?
Guten Abend zusammen,
ich bin gerade dabei, ein kleines Tool zu schreiben. Jetzt habe ich folgendes Probblem. Ich habe Tool A, in das ich einen Text eingebe. Dieser Text wird gespeichert. Tool B soll diesen Text nun wieder auslesen. Problem an der Sache ist, dass ich hierbei die Windos API benutze. Und jetzt habe ich ein Problem. Wenn ich den Text als "Delphi"-String speicher, und dann auslese, bekomme ich eine ganz wirre Zeichenfolge angezeigt. Jetzt habe ich mich schlau gemacht und herrausgefunden, dass Delphi Stings nicht das selbe sind wie String von Windows. Weil dort irgendwie die Nulltermienierung fehlt. Ok dachte ich mir, dann arbeite ich halt mit Ansistrings. Dort sind die Strings ja nullterminiert. Doch das hat nichts verändert. Immernoch die komische Zeichenkette. Dann habe ich aber einen Tipp gelesen, dass man einfach an den Text ein #0 anhängen soll, um so die Nullterminierung manuell zu setzen. Das habe ich gemacht und siehe da, es hat funktioniert. Doch jetzt frage ich mich, warum das so geht, aber nicht mit Ansstrings? Der Text wurde bei beiden Versuchen in einem Editfeld eingegeben. |
AW: Strings und Ansistrings, Nullterminiert?
Welche Windows-API? in was sind beide Programme geschrieben? Wie schaut ein Beispiel mit "Komischen" Zeichen aus (Text Ursprung <-> Text komisch).
Hätte da schon eine Idee was du falsch machst. |
AW: Strings und Ansistrings, Nullterminiert?
1. Also Programmiert in Delphi.
2. UpdateResource etc. wird benutzt. 3.1 Eingangstext = Test 3.2 Ausgangstext = ![]() |
AW: Strings und Ansistrings, Nullterminiert?
Ja, Delphi-Strings sind Nullterminiert, als Kompatibilität zum PChar, obwohl sie selber allerdingt ein Längenbyte (Integer) besitzen.
Castet man einen String nach PChar, AnsiString nach PAnsiChar oder UnicodeString/WideString nach PWideChar, greift die Compilermagic, welche die Referenzzählung der Delphi-Strings beachtet und zusätzlich noch den Leer-String besonders behandelt. Und ab Delphi 2009 mußt du mit Unicode aufpassen. PS: Rate mal, warum man im Forenprofil angeben kann, was man nutzt? In Deinem Fall hast du den AnsiString wohl radikal nach PWideChar gecastet ... das macht man nicht. :warn: Oder du hast dich verpointert und statt den Textdaten einen Zeiger auf die Variable ... das ist auch falsch, :roll: Und da du nicht verrätst, wie dein Code aussieht, wird dir auch keiner helfen können. |
AW: Strings und Ansistrings, Nullterminiert?
Ganz einfach.
Windows verwendet PChar. PChar ist ein Pointer(Adresse) zum Anfang des Textes, aber nicht wo er aufhört. Jedoch kannst du mit einem #0 am Ende des Textes, bevor du ihn an die API übergibst, sagen dort hört der Text auf. Delphi-Strings können solche #0 (Nullterminiert) Zeichen anzeigen, bzw. speichern, PChar kann dies nicht, wenn er ein #0 erkennt, beendet er den Text. Also in etwa so:
Delphi-Quellcode:
Das Gleiche gilt für AnsiStrings, jedoch vorsicht. Caste nicht einen String(Unicode) zu PAnsiChar.
var S : String;
begin S := 'Hallo' + #0; //Diesen String als PChar gecastet übergeben. end; Das würde auch komishce Zeichen ergeben. Oder umgekehrt. P.S. : Verdammt war jemand schneller :-D |
AW: Strings und Ansistrings, Nullterminiert?
Sorry, meine vorherige Antwort sollte garnicht so "böse" rüberkommen wie es jetzt aussieht xD.
Jop Forumprofil wird geupdated. Also ich benutze Delphi RAD Studio XE. Also wie ich schon ansprach, muss ich einen String in einen AnsiString umwandeln. Dachte es reicht, wenn ich einfach
Code:
schreibe.
Text := AnsiString(Edit1.Text);
Denn das habe ich versucht aber es geht nicht. Das ich den Pointer falsch gesetzt habe schließe ich mal aus, da ja wie gesagt alles wunderbar funktioniert, wenn ich folgendes schreibe:
Code:
Text := Edit1.Text + #0;
Hier also mein Code mit UpdateResource:
Code:
function AddString(text,delimiter : string) : Boolean;
var hUpdateRes : THandle; lpResLock : ^string; begin lpResLock := @text; hUpdateRes := BeginUpdateResource('Ausgabe.exe', False); if hUpdateRes = 0 then showmessage('Could not open file'); result := UpdateResource(hUpdateRes, RT_String, PChar(delimiter), 0, PChar(text), succ(length(text))*sizeof(char)); EndUpdateResource(hUpdateRes, false); end; Und hier mein Ausruf:
Code:
DoXOr ist einfach nur eine kleine XOr verschlüsselung.
procedure TForm1.Button1Click(Sender: TObject);
begin AddString(DoXOr(AnsiString(Edit1.Text), 1000), 'TEXT1'); end; Wie gesagt, wenn ich die Funktion so aufrufe funktioniert es wunderbar:
Code:
procedure TForm1.Button1Click(Sender: TObject);
begin AddString(DoXOr(Edit1.Text + #0), 1000), 'TEXT1'); end; Edit: Aber ich habe doch einen String, den ich in einen AnsiString wandeln muss.
Code:
funktioniert also nicht so einfach ?
AddString(DoXOr(AnsiString(Edit1.Text), 1000), 'TEXT1');
PS: Was heißt gecastet? xD Konvertiert? |
AW: Strings und Ansistrings, Nullterminiert?
Verlangt DoXOr eine AnsiString oder String?
Hört sich so an, als würde DoXOr den String/AnsiString zu PChar/PAnsiChar casten (umwandeln). Ab Delphi 2009 glaub ich, sind Strings Unicode d.h. 1 Zeichen = 2 Bytes. 1 AnsiZeichen = 1 Byte. Du kannst String einfach zu AnsiString casten, da Delphi die konvertieren von Unicode zu ANSI alleine macht. Wenn du mit PAnsiChar und PChar arbeitest, musst du darauf achten den Text in den richtigen String zucasten. PChar = String, PAnsiChar = AnsiString. Falls du einer String-Variable einen AnsiString zuweist, macht Delphi es auch von alleine. Beim übergeben an eine API, musst entweder so:
Delphi-Quellcode:
oder die APIs mit dem A am Ende nehmen, mit dennen kannst du AnsiString direkt senden.
var Text : PChar;
AText : AnsiString; begin Text := PChar(String(AText)); end; z.b. SendMessageA; Das würde es so gehen:
Delphi-Quellcode:
EDIT: Succ brauchst du nicht.
var Text : PAnsiChar;
AText : AnsiString; begin Text := PAnsiChar(AText); end;
Delphi-Quellcode:
result := UpdateResource(hUpdateRes, RT_String, PChar(delimiter), 0, PChar(text), succ(length(text))*sizeof(char)); |
AW: Strings und Ansistrings, Nullterminiert?
@NickelM: Wie gesagt, Delphi-String enthält schon eine #0 am Ende. Zusätzlich zum enthaltenen Text liegt diese hinter dem letzen Zeichen.
Ausnahme ist nur der ![]() WideString ist kein Delphi-String. Da drin ist ein OLE-String der WinAPI gekapselt. |
AW: Strings und Ansistrings, Nullterminiert?
Ich danke euch schonmal für die ganzen Antworten, aber irgendwie hilft mir das nicht wirklich.
Der Erste sagt: Zitat:
Zitat:
Wie gesagt, ich hab Edit1.Text ja zu nem AnsiString umgewandelt, was aber nicht geholfen hat. Oder soll ich statt AnsiString, PChar benutzen? Ich hab das Gefühl wir drehen uns im Kreis. Ihr wisst woran es liegt und helft mir schon und dafür bin ich sehr dankbar. Aber irgendwie kommt es mir so vor, als wenn mir das alles noch nicht weiter hilft Sorry für meine Unwissenheit. |
AW: Strings und Ansistrings, Nullterminiert?
String-Resourcen sind schon immer Unicode (seit WinNT) und nun rate mal, in welchem Format du den "Text" an UpdateResource übergeben mußt.
|
AW: Strings und Ansistrings, Nullterminiert?
Zitat:
|
AW: Strings und Ansistrings, Nullterminiert?
Davor wußte ich halt nicht, aber seit NT und vorallem jetzt sind sie es auf jeden Fall. :duck:
|
AW: Strings und Ansistrings, Nullterminiert?
Zitat:
WideString ist kein Delphi-String? Auch nicht in den neuen Delphi Versionen? Bei Delphi 5 entspricht WideString einem Delphi 2009+ String, zumindest hat WideString dort 2 Bytes je Zeichen. Und ein Delphi 5 String hat 1 Byte je Zeichen, da noch nicht Unicode "standard" war. Ist nicht eigentlich der String-Typ der neuen Versionen, genauso wie ein WideString in den neuen Versionen. Sie haben doch beide 2 Byte je Zeichen, genauso wie UnicodeString. Neueren Delphis haben WideString,UnicodeString,AnsiString und String. String und AnsiString ist klar. Aber die anderen stammen doch vom gleichen Typ. Sind die nur noch wegen der Kompatibilität vorhanden, oder? Weil Delphi 5 kennt er nur WideString, AnsiString und String. Noch eine Frage, sorry wenn ich grad ein bischen vom Thema abkomme :oops:, wie meinst du das mit OLE-String der WinAPI???? |
AW: Strings und Ansistrings, Nullterminiert?
Zitat:
Gegenüber dem AnsiString und dem ab D2009 vorhandenen Unicodestring hat er keine Referenzzählung Zitat:
Im Unicodestring wird auch gespeichert welche Codierung der eigentliche String hat. |
AW: Strings und Ansistrings, Nullterminiert?
Der WideString ist und war immer "nur" eine Weiterleitung/Kapselung von Funktionen der oleaut32.dll
![]() ![]() ![]() ![]() Der UnicodeString ab Delphi 2009 ist dageben genauso aufgebaut, wie der AnsiString. Das ist der Aufbau des UnicodeString (sowie des AnsiString): Ab D2009 wurde nur noch das codePage und elemSize eingeführt, für das besch* umgesetzte StringChecking.
Delphi-Quellcode:
Der interne String-Zeiger zeigt auf data[0] oder auf NIL, bei einem Leerstring.
StrRec = packed record
codePage: Word; elemSize: Word = SizeOf(WideChar); refCnt: Integer; length: Integer; data: array[0..x] of WideChar; null: Char = #0; end; |
AW: Strings und Ansistrings, Nullterminiert?
Es funktioniert einfach nicht,ich kann machen was ich will.
ich habe jetzt so ziemlich alles probiert was nur geht. Ich bin nochmal alles durch gegangen. Also: Meine Funktion "AddString" benötigt also einen nullterminierten String. Also dachte ich mir, dann muss das Result meiner XOR Verschlüsselung ja ein Ansistring sein. Also habe ich einfach das Result der XOR Funktion als Ansistring deklariert, aber immernoch der gleiche Fehler. Jetzt weiß ich wirklich nicht weiter. Es ist doch alles so, wie es zu sein hat oder nicht? |
AW: Strings und Ansistrings, Nullterminiert?
Kann es sein, dass der Fehler in deinem Verschlüsselungscode liegt?
|
AW: Strings und Ansistrings, Nullterminiert?
Code:
function DoXOr(Buffer :string; Key : integer) : ansistring;
var i,c,x :Integer; begin for i := 1 to Length(Buffer) do begin c := Integer(Buffer[i]); x := c xor Key; Result := Result + Char(x); end; end; Buffer ist mein String und Key ist der Verschlüsselungsinteger, welchen bei mir 15 ist. |
AW: Strings und Ansistrings, Nullterminiert?
Versuch mal stat Char, AnsiChar. Sollte eigentlich kein Unterschied machen, da Delphi soviel ich weis es umcasten müsste.
|
AW: Strings und Ansistrings, Nullterminiert?
Und versuch mal Byte statt Integer.
|
AW: Strings und Ansistrings, Nullterminiert?
Also es geht immer noch nicht, auch nach den Änderungen.
Doch jetzt hae ich spaßeshalber einfach mal die XOr Verschlüsselung weg gelassen und siehe da, es funktioniert alles. Ich muss nicht einmal AnsiString benutzen, selbst mit nem "normalen" String geht es wunderbar. Bedeutet also, dass irgendwas mit der XOr funktion nicht stimmt. |
AW: Strings und Ansistrings, Nullterminiert?
Gibts nicht 'ne kleine Compilerwarnung das der result nicht initialisiert ist?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:35 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