2017-10-04 82 views
2

我正在使用德爾福6.德爾福6可以將UTF-8葡萄牙語轉換爲WideString嗎?

我想解碼一個葡萄牙UTF-8編碼的字符串到WideString,但我發現它不正確解碼。

原文爲"ANÁLISE8"。使用UTF8Decode()後,結果爲"ANALISE8""A"上方的符號消失。

下面是代碼:

var 
    f : textfile; 
    s : UTF8String; 
    w, test : WideString;  
begin 
    while not eof(f) do 
    begin 
    readln(f,s); 
    w := UTF8Decode(s); 

我怎樣才能解碼葡萄牙UTF-8字符串WideString是否正確?

+0

使用MultiByteToWideChar –

+0

很可能你是文件不是用UTF-8編寫的。以UTF-8編寫的文件通常具有3字節[字節順序標記序列](https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8),如果文件不是安全地假設它使用系統的默認Ansi代碼頁。在這種情況下,將數據存儲在「UTF8String」中不會產生UTF-8 ... –

+0

您是如何確定您的代碼無法正常工作的?我敢打賭,你將WideString轉換爲ANSI。 –

回答

2

請注意,在Delphi 6中執行UTF8Decode()是不完整的。具體來說,它不支持編碼的4字節序列,這些序列需要處理高於U+FFFF的Unicode碼點。這意味着UTF8Decode()只能解碼UCS-2範圍內的Unicode代碼點,而不是完整的Unicode代碼庫。因此,在Delphi 6中(以及直到Delphi 2007一直到Delphi 2009最終都修復了這個問題),基本上無法使用UTF8Decode()

嘗試使用Win32 MultiByteToWideChar()函數來代替,例如:

uses 
    ..., Windows; 

function MyUTF8Decode(const s: UTF8String): WideString; 
var 
    Len: Integer; 
begin 
    Len := MultiByteToWideChar(CP_UTF8, 0, PAnsiChar(s), Length(s), nil, 0); 
    SetLength(Result, Len); 
    if Len > 0 then 
    MultiByteToWideChar(CP_UTF8, 0, PAnsiChar(s), Length(s), PWideChar(Result), Len)); 
end; 

var 
    f : textfile; 
    s : UTF8String; 
    w, test : WideString; 
begin 
    while not eof(f) do 
    begin 
    readln(f,s); 
    w := MyUTF8Decode(s); 

話雖這麼說,你ANÁLISE8串落在UCS-2的範圍內,所以我在Delphi 6測試UTF8Decode()並解碼UTF-8編碼形式ANÁLISE8就好。我會得出這樣的結論之一:

  • UTF8String變量不包含UTF-8的ANÁLISE8編碼形式開始(字節序列41 4E C3 81 4C 49 53 45 38),而是包含了ASCII字符串ANALISE8代替(字節序列41 4E 41 4C 49 53 45 38)因爲ASCII是UTF-8的一個子集,所以它將按原樣解碼。仔細檢查你的文件,並輸出Readln()

  • WideString包含ANÁLISE8正確的預期,但你現在的樣子輸出/調試它(你沒有顯示)被其轉換爲ANSI,在轉換過程中丟失Á

+0

@DavidHeffernan:我更新了我的答案 –

+0

@DavidHeffernan:我更新了我的答案 –

+0

嗨,非常感謝,我只是將UTF-8代碼轉換爲HEX並查看(字節序列41 4E C3 81 4C 49 53 45 38),所以我認爲該文件必須是UTF-8格式...感謝您的函數MyUTF8Decode,只是使用它而不是UTF8Decode和結果是一樣的,葡萄牙字符變成英文 –