AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Unicode-Umwandlung

Ein Thema von blackdrake · begonnen am 9. Aug 2007 · letzter Beitrag vom 12. Aug 2007
Antwort Antwort
Seite 2 von 2     12   
Ydobon

Registriert seit: 3. Mär 2006
264 Beiträge
 
Delphi 11 Alexandria
 
#11

Re: Unicode-Umwandlung

  Alt 11. Aug 2007, 18:08
Bei der String->WideString Zuweisung bastelt Delphi automatisch den MultiByteToWideChar Aufruf in den Code, das klappt aber nicht, wenn z.B. über s:=#$53#$30#$8C#$30#$6F#$30#$5E#$97#$38#$00 ein String direkt mit den Bytewerten eines WideString gefüttert wird, die in einem AnsiString normalerweise nicht vorkommen können. Die Bytefolgen oben dürften bereits UTF-16 sein, Shift-JIS sieht anders aus.
Wenn es hier ein Problem gibt, dann vermutlich lediglich das Ausleseergebnis der Datei direkt in einen WideString zu bekommen und nicht irgendwelche Konvertierungen.
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#12

Re: Unicode-Umwandlung

  Alt 11. Aug 2007, 20:14
Hallo,

die Zeichenfolge #$53#$30#$8C#$30#$6F#$30#$5E#$97#$38#$00 ist in Delphi immer ein AnsiString und könnte tatsächlich UTF-16 Hiragana sein. Ich hatte mir den String nicht genau angesehen, weil Windows in Japan mit CP 932 (Shift-JIS) arbeiten soll.

Das Arbeiten mit dem Literal ist ja wohl nur ein Test, da ja der eigentliche Dateiname über eine Funktion ermittelt wird. Die Interpretation als WideString ist so möglich:

Delphi-Quellcode:
var
  s: string;
  ws: WideString absolute s;
begin
  s := #$53#$30#$8C#$30#$6F#$30#$5E#$97#$38#$00;
  ShowMessage(ws);
end;
Freundliche Grüße
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#13

Re: Unicode-Umwandlung

  Alt 11. Aug 2007, 23:11
Zitat von Ydobon:
Ich blick hier anscheinend nicht ganz durch, warum UTF-16 nach UTF-16 wandeln? Wenn ich
Delphi-Quellcode:
var s: String;
    ws: PWideChar;
   l: Integer;
begin
  s := #$53#$30#$8C#$30#$6F#$30#$5E#$97#$38#$5E#$6B#$30#$ED#$77#$44#$30#$C6#$30#$AD+
       #$30#$B9#$30#$C8#$30#$67#$30#$42#$30#$8B#$30#$02#$30#$2E#$00#$69#$00#$64#$00#$78#$00;
  ws:=PWChar(@s[1]);
  TntEdit1.Text:=ws;
bekomm ich (ohne führendes Nullbyte) これは非常に短いテキストである。.idx bzw. mit s := #$53#$30#$8C#$30#$6F#$30#$5E#$97#$38; ergibt sich (+#$00) これは非8. Soll das in etwas herauskommen? Wenn du bereits Unicode hast, dann gibt es da doch nichts mehr umzuwandeln. Wie liest du die Info2 denn aus?
Hallo. In meinem Beispiel soll es wirklich これは非常に短いテキストである (Babelfish: This is a very short text) heißen. Noch habe die die Routine für die Auslesung aus der INFO2 noch nicht geschrieben. Mein Beispielnamen habe ich durch den Hexeditor aus der INFO2 manuell ausgelesen.

Zitat von marabu:
Hallo Robert,

Zitat von blackdrake:
... Als erstes brauche ich eine Funktion, die ANSI in Unicode umwandelt. ...
wenn Daniel die Funktion StringToWideString() so verwendet, wie er es zeigt - d.h. mit CP_ACP = 0 - dann kann er auch gleich mit einer Zuweisung arbeiten - Delphi macht dann genau das gleiche. Mich macht aber seine Erwähnung von japanischen Zeichen im Kommentar stutzig. Wenn wirklich ein SJIS-Dateiname vorliegt, dann sind die beiden Funktionen hilfreich, da die CodePage unabhängig von der aktuellen frei gewählt werden kann.

Freundliche Grüße
Ich verstehe das ganze nicht so richtig... ich muss doch erstmal Unicode -> WideChar/WideString (?) umwandeln, damit die Datei korrekt umbenannt wird...

Zitat von marabu:
Hallo,

die Zeichenfolge #$53#$30#$8C#$30#$6F#$30#$5E#$97#$38#$00 ist in Delphi immer ein AnsiString und könnte tatsächlich UTF-16 Hiragana sein. Ich hatte mir den String nicht genau angesehen, weil Windows in Japan mit CP 932 (Shift-JIS) arbeiten soll.

Das Arbeiten mit dem Literal ist ja wohl nur ein Test, da ja der eigentliche Dateiname über eine Funktion ermittelt wird. Die Interpretation als WideString ist so möglich:

Delphi-Quellcode:
var
  s: string;
  ws: WideString absolute s;
begin
  s := #$53#$30#$8C#$30#$6F#$30#$5E#$97#$38#$00;
  ShowMessage(ws);
end;
Freundliche Grüße
Folgender Code:

Delphi-Quellcode:
begin
  MoveFileW('testa', #$53#$30#$8C#$30#$6F#$30#$5E#$97#$38#$00);
end;
benennt meine Datei testa in S0Œ0o0^—8 um...

Und folgender Code:

Delphi-Quellcode:
begin
  MoveFileW('testa', #$53#$30#$8C#$30#$6F#$30#$5E#$97#$38#$5E#$6B#$30#$ED#$77#$44#$30#$C6#$30#$AD#$30#$B9#$30#$C8#$30#$67#$30 +
             #$42#$30#$8B#$30#$02#$30#$2E#$00#$69#$00#$64#$00#$78#$00#$00);
end;
macht gar nichts. Ich habe am Ende noch eine Nullterminierung (bei Unicode $00 $00) hinzugefügt. Aber irgendwie funktioniert das nicht. Die Datei sollte sich in これは非常に短いテキストである.idx umbennen.

Weiß irgendwer Rat? Ich bin im Moment total verwirrt mit Unicode und WideChar, WideString und Pointern usw... Ist eine Grauzone in meinem Gebiet.

Gruß
blackdrake

[edit=mkinzler]Umbruch in Code eingefügt Mfg, mkinzler[/edit]
Daniel Marschall
  Mit Zitat antworten Zitat
Ydobon

Registriert seit: 3. Mär 2006
264 Beiträge
 
Delphi 11 Alexandria
 
#14

Re: Unicode-Umwandlung

  Alt 12. Aug 2007, 00:28
Was soll Delphi denn machen? In der Funktion steht eine Folge von Charwerten, für Delphi ist das natürlich ein AnsiString; #$53='S', #$30='0' usw., den es damit hilfsbereit vor dem Funktionsaufruf erst einmal zum WideString macht, in der Annahme jedes Byte bedeutet ein eigenes Zeichen.
Zum Versuchen kannst du die Sache einem AnsiString zuweisen und entweder wie marabu einen WideString mit dem gleichen Speicherbereich benutzen (aber besser mit MessageBoxW und nicht ShowMessage) oder halt die Pseudokonvertierung PWChar(@s[1]) probieren.

Ich denke aber, dass das alles gar nicht notwendig ist. Die Schwierigkeiten bei den Beispielen kommen vor allem durch die direkte Bytezuweisung der Hexeditorergebnisse an einen AnsiString (ein WideChar in 2 ausgewiesene Char). Sollte bei deinem Vorhaben aber gar nicht auftreten, wenn du den Namen bereits als WideString=UTF-16 aus der Datei herausliest. Wichtig ist also die Routine, mit der du die Datei ausliest.
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#15

Re: Unicode-Umwandlung

  Alt 12. Aug 2007, 00:33
Hallo.

Ich habe es aufgrund der Vorlage von Ydobon herausgefunden, wie es funktioniert!

Delphi-Quellcode:
function unicode(inp: string): PWideChar;
begin
  result := PWChar(@inp[1]);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  movefilew('testa', unicode(#$53#$30#$8C#$30#$6F#$30#$5E#$97#$38#$5E#$6B#$30#$ED#$77#$44#$30#$C6#$30#$AD#$30#$B9#$30#$C8#$30#$67#$30#$42#$30#$8B#$30 +
        #$02#$30#$2E#$00#$69#$00#$64#$00#$78#$00));
end;
Ich muss jetzt also beim Papierkorb bei der Info2 Auslesung beim richtigen Offset solange 2 Bytes einlesen, bis ein Byte-Paar $00 $00 ist. Dann höre ich auf, die Bytepaare an s (string) anzuhängen. Die $00 $00 Null-Terminierung muss nicht bei movefilew() vorhanden sein.

Gruß
blackdrake

[edit=mkinzler]Umbruch in Code eingefügt Mfg, mkinzler[/edit]
Daniel Marschall
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#16

Re: Unicode-Umwandlung

  Alt 12. Aug 2007, 11:22
Hi,
Dein Code ist so nicht wirklich sauber. Du gibst hier einen Zeiger auf einen Speicherbereich zurück, von dem Du nicht weißt wie lang dieser gültig ist.
Am deutlichsten kann man das an einem Beispiel machen:

Delphi-Quellcode:
function doFoo: PWideChar;
var s: String;
begin
  s := #$53#$30#$8C#$30$00$00;
  result := unicode(s);
end;

procedure doBar;
var p: PWideChar;
begin
  p := doFoo;
  // und hier knallt es dann beim Zugriff auf p
end;
Der Zeiger, den Unicode liefert, der zeigt in doFoo, nach dem Aufruf von unicode(s) noch auf das erste Element von s. Wird die Funktion verlassen, wird s durch Delphi frei gegeben, das Ergebnis der Funktion zeigt aber weiterhin auf diesen Speicher. In doBar steht jetzt eine Adresse zur Verfügung, die ins Daten-Nirvana zeigt. Mit etwas Glück bekommst Du nur eine Zugriffsverletzung, da Delphi erkennt, dass Du auf ungültigen Speicher zugreifst. Mit etwas Pech liest/schreibst Du zufällig irgendwo in den Speicher (Deines Programms) und hast ein undefiniertes Verhalten. Dieses Verhalten kann sich bei jedem Aufruf völlig anders verhalten (je nachdem was gerade wo im Speicher steht und was Du zufällig überschreibst), solche Fehler sind deswegen sehr schwer zu finden!

Besser ist es deshalb, wenn Du in der Methode einen neuen Speicherbereich allozierst und dessen Adresse zurückgibst. Wichtig ist es dann, dass Du auch für die Freigabe sorgen musst (aber bis zur expliziten Freigabe wäre die Adresse gültig!).

Delphi-Quellcode:
function unicode(inp: string): PWideChar;
begin
  GetMem(result, length(inp));
  Move(inp[1], result, length(inp));
end;

procedure TForm1.Button1Click(Sender: TObject);
var ustr: PWideChar;
begin
  ustr := unicode(#$53#$30#$8C#$30#$6F#$30#$5E#$97#$38#$5E#$6B#$30#$ED#$77#$44#$30#$C6#$30#$AD#$30#$B9#$30#$C8#$30#$67#$30#$42#$30#$8B#$30#$02#$30#$2E#$00#$69#$00#$64#$00#$78#$00);
  movefilew('testa', ustr);
  FreeMem(ustr); // erst hier wird ustr ungültig
end;
Das Ydobon eigentlich meinte (gerade mal gelesen) war sicherlich, dass Du im gleichen Scope wie der String (also ohne Aufruf der Funktion unicode) diesen Cast hättest durchführen können, auch das ist natürlich möglich:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var ustr: PWideChar;
begin
  ustr := #$53#$30#$8C#$30#$6F#$30#$5E#$97#$38#$5E#$6B#$30#$ED#$77#$44#$30#$C6#$30#$AD#$30#$B9#$30#$C8#$30#$67#$30#$42#$30#$8B#$30#$02#$30#$2E#$00#$69#$00#$64#$00#$78#$00;
  movefilew('testa', PWideChar(@ustr[1]));
end;
Hier ist die Adresse für den Aufruf von movefilew gültig, da die aufgerufene Methode synchron arbeitet. Kritisch wäre das erst, wenn Du hier eine asynchrone Methode hast, die also parallel abgearbeitet wird und vor der vollständigen Bearbeitung zurückkehrt.

Gruß Der Unwissende
  Mit Zitat antworten Zitat
Ydobon

Registriert seit: 3. Mär 2006
264 Beiträge
 
Delphi 11 Alexandria
 
#17

Re: Unicode-Umwandlung

  Alt 12. Aug 2007, 13:19
Mal so nebenbei, könntet ihr eure überlangen Strings bitte auf mehrere Zeilen verteilen, da genügt schon ein '+', mein Bilschirm ist einfach nicht so groß.

Abgesehen von der Sauberkeit der Codes (Wie sicher ist eigentlich der Speicherbereich einer lokalen Variable außerhalb ihrer Funktion?) sollte blackdrake mit Konvertierungen gar nichts zu tun haben, da alles schon als Unicode also WideString vorliegt. Es geht eine Routine zum Auslesen der Datei bereits als WideString.
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#18

Re: Unicode-Umwandlung

  Alt 12. Aug 2007, 16:38
Hallo.

Ich habe die Funktion fertiggestellt: http://www.delphipraxis.net/internal...t.php?t=116139

Die Auslagerung in Unicode() habe ich dabei entfernt - war nur hier zur Vereinfachung. Ich gehe mal davon aus, dass der Code in meiner Funktion nun sauber ist, da ich auf einen Speicherbereich zeige, der in der Funktion noch verfügbar ist.

Delphi-Quellcode:
var
  s: string;
  buf2: array[0..1] of char;

...
fs.seek(unicode_source_position+i*record_length, soFromBeginning);
s := '';
repeat
  fs.ReadBuffer(buf2[0], 1);
  fs.ReadBuffer(buf2[1], 1);
  if (buf2[0] = #0) and (buf2[1] = #0) then
    break
  else
    s := s + buf2[0] + buf2[1];
until false;
result := PWChar(@s[1]); // Unicode-Umwandlung
...
Ist das jetzt also OK?

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#19

Re: Unicode-Umwandlung

  Alt 12. Aug 2007, 18:11
Hallo,

wieso verwendest Du eigentlich nicht gleich einen WideString?
Ungefähr so:
Delphi-Quellcode:
function ReadWideString(const Stream: TStream): WideString;
var
  S: WideString;
  WC: WideChar;
begin
  S := '';
  repeat
    Stream.ReadBuffer(WC, 2);
    if (WC <> #0) then
      S := S + WC;
  until WC = #0;
  Result := S;
end;
Außerdem gibst Du wohl immer noch einen Pointer auf eine lokale Variable zurück. Das geht nach hinten los. Gib lieber einen WideString zurück und verwende diesen.

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#20

Re: Unicode-Umwandlung

  Alt 12. Aug 2007, 18:23
@xaromz: Vielen Dank für die Funktion!
Daniel Marschall
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:53 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz