Autor Beitrag
thomasoop
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29


D5 + D6 Enterprise
BeitragVerfasst: Fr 07.10.05 12:06 
Hallo Zusammen,
ich habe eine Datei die (so vermute ich) im UTF8 Format(habe hier im Forum etwas rumgesucht und bin auf UTF8 gestoßen) vorliegt bzw so immer erzeugt wird.
Wenn ich Datei in ein Memo lade dann werden alle Sonderzeichen "falsch" dargestellt.

Habe mir eine Funktion geschrieben die einige Sonderzeichen umwandelt.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function TfrmImpo.UTF8toDOS ( line : String ) : String;
Begin
  line := StringReplace ( line, 'Ä''Ä', [rfReplaceAll] );
  line := StringReplace ( line, 'ä''ä', [rfReplaceAll] );
  line := StringReplace ( line, 'â''â', [rfReplaceAll] );

  line := StringReplace ( line, 'Ö''Ö', [rfReplaceAll] );
  line := StringReplace ( line, 'ö''ö', [rfReplaceAll] );

  line := StringReplace ( line, 'é''é', [rfReplaceAll] );
  line := StringReplace ( line, 'è''è', [rfReplaceAll] );

  line := StringReplace ( line, 'ü''ü', [rfReplaceAll] );
  line := StringReplace ( line, 'Ü''Ü', [rfReplaceAll] );

  line := StringReplace ( line, 'ß''ß', [rfReplaceAll] );
  result := line;
End;


Da es aber noch eine ganze Menge an Sonderzeichen gibt, wüsste ich gerne ob es nicht eine einfachere Methode gibt.
Bin für jeden Tip dankbar.

Gruß
Thomas(OOP)

Moderiert von user profile iconAXMD: Code- durch Delphi-Tags ersetzt
AXMD
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Fr 07.10.05 12:26 
Bin mir nicht sicher, aber hilft dir OEMToChar vielleicht? Hab grade kein Delphi hier in der FH.

AXMD
thomasoop Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29


D5 + D6 Enterprise
BeitragVerfasst: Fr 07.10.05 12:46 
Nein, klappt leider nicht.
Sieht nach der Konvertierung nicht viel besser aus ;)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 07.10.05 13:02 
Das hat damit auch erstmal nix zu tun, das ist ja für die Konvertierung ANSI <-> DOS, aber nicht für Unicode...

@thomasoop: Bist du sicher, dass du das im DOS und nicht im Windows (ANSI) Format haben willst?

Hier jedenfalls eine Funktion, die die Konvertierung mit Hilfe von ner Utility-Sammlung automatisch macht, ist aber noch nicht ganz fertig, da fehlt noch einiges...
Für deinen Fall reichts aber wohl schon...

(Das stammt aus meinem Open-Source-Editor Scriba 2005...)

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
type
  TScribaFileFormat = (ffPC, ffUnix, ffMac, ffUnknown);
  TScribaCharacterSet =
    (csAnsi, csAscii, csUnicodeLE, csUnicodeBE, csUTF8, csUnknown); 

//(...)

uses
  cUnicodeReader, cUnicodeCodecs;

//(...)

function GetFileContentsAsString(uFilename: String;
  var uFileFormat: TScribaFileFormat; var uCharSet: TScribaCharacterSet): String;

  function DetectUnicode(var uSize: Integer; var uBigEndian: Boolean): Boolean;
  var
    tmp: TFileStream;
    signature: array[0..1of Byte;
  begin
    tmp := TFileStream.Create(uFilename, fmOpenRead);
    if tmp.Size < 2 then
    begin
      Result := False;
      tmp.Free;
      Exit;
    end;
    tmp.ReadBuffer(signature, SizeOf(signature));
    uBigEndian := (signature[0] = $FEand (signature[1] = $FF);
    Result := ((signature[0] = $FFand (signature[1] = $FE)) or uBigEndian;
    uBigEndian := Result and uBigEndian;
    uSize := tmp.Size;
    tmp.Free;
  end;

  function DetectUTF8(uText: String): Boolean;
  begin
    Result := (Length(uText) > 2and (Ord(uText[1]) = $EF)
      and (Ord(uText[2]) = $BBand (Ord(uText[3]) = $BF);
  end;

  function DetectAnsi(uText: String): Boolean;
  begin
    Result := (Pos('ä', uText) > 0or (Pos('ö', uText) > 0)
      or (Pos('ü', uText) > 0);
  end;

  function DetectAscii(uText: String): Boolean;
  begin
    Result := (Pos('„', uText) > 0or (Pos('”', uText) > 0)
      or (Pos('', uText) > 0)
      and not ((Pos('ä', uText) > 0or (Pos('ö', uText) > 0)
        or (Pos('ü', uText) > 0));
  end;

  function DetectFileFormat(uText: String): TScribaFileFormat;
  begin
    if Pos(#13#10, uText) > 0 then
      Result := ffPC
    else if Pos(#10, uText) > 0 then
      Result := ffUnix
    else if Pos(#13, uText) > 0 then
      Result := ffMac
    else
      Result := ffPC;
  end;

var
  tmp: TUnicodeMemoryReader;
  Size: Integer;
  BigEndian: Boolean;
  tmpFile: TFileStream;
  tmpMemStream: TMemoryStream;
  i: Integer;
  a, b: Byte;
begin
  if DetectUnicode(Size, BigEndian) then
  begin
    tmpFile := TFileStream.Create(uFilename, fmOpenRead);
    tmpMemStream := TMemoryStream.Create;
    if BigEndian then
    begin
      for i := 0 to tmpFile.Size div 2 - 1 do
      begin
        tmpFile.ReadBuffer(a, SizeOf(a));
        tmpFile.ReadBuffer(b, SizeOf(b));
        tmpMemStream.WriteBuffer(b, SizeOf(b));
        tmpMemStream.WriteBuffer(a, SizeOf(a));
      end;
      uCharSet := csUnicodeBE;
    end
    else
    begin
      tmpMemStream.CopyFrom(tmpFile, tmpFile.Size);
      uCharSet := csUnicodeLE;
    end;
    tmpFile.Free;

    tmp := TUnicodeMemoryReader.Create(tmpMemStream.Memory, tmpMemStream.Size);
    tmp.Skip(1);
    Result := tmp.ReadUTF8Str(Size - 1);
    tmp.Free;
    tmpMemStream.Free;
  end
  else
  begin
    uCharSet := csAnsi;
    with TStringList.Create do
    begin
      LoadFromFile(uFilename);
      Result := Text;
    end;
    if DetectUTF8(Result) then
    begin
      Delete(Result, 13);
      uCharSet := csUTF8;
    end
    else if DetectAscii(Result) then
    begin
      OEMToChar(PChar(Result), PChar(Result));
      uCharSet := csAscii;
    end;
  end;
  uFileFormat := DetectFileFormat(Result);
end;

Die var-Parameter geben das erkannte Format zurück.

Dazu brauchst du auch noch:
fundementals.sourceforge.net/
(Die Utilities mit Unicode)

Vielleicht gehts mit den Utilities auch einfacher, keine Ahnung. Und wenn du das wirklich im DOS und nicht im ANSI-Format haben willst, dann musst du das tatsächlich noch mit der bereits angesprochenen Funktion OEMToChar bzw. CharToOEM umwandeln.
Bernhard Geyer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 721
Erhaltene Danke: 3



BeitragVerfasst: Sa 08.10.05 12:47 
user profile iconthomasoop hat folgendes geschrieben:

Da es aber noch eine ganze Menge an Sonderzeichen gibt, wüsste ich gerne ob es nicht eine einfachere Methode gibt.
Bin für jeden Tip dankbar.


Ja. Es gibt ab D6 die (undokumentierten) Funktionen UTF8Encode und UTF8Decode in System.pas welche die gewünschte Konviertierugn bieten.
thomasoop Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29


D5 + D6 Enterprise
BeitragVerfasst: Mi 12.10.05 08:41 
Ich benutze z.Z. D5
Wäre mal ein Grund auf D6 umzusteigen.

aber ich denke ich werde jaenicke's Methode mal ausprobieren

Danke für die Hilfe

Gruß
Thomas(OOP)
Bernhard Geyer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 721
Erhaltene Danke: 3



BeitragVerfasst: Do 13.10.05 08:28 
user profile iconthomasoop hat folgendes geschrieben:
Ich benutze z.Z. D5
Wäre mal ein Grund auf D6 umzusteigen

Es gibt in der Jedi entsprechende Funktionen auch für Delphi 5.
Oder schau mal bei Mike Lischke vorbei (www.lischke-online.de/UnicodeLibrary.php).