Delphi中处理UTF8格式的文本

前面有篇文章写了DELPHI中UTF-8格式转ANSI格式。当时那个格式仅限于Windows记事本保存的UTF-8格式,不支持一般的UTF-8格式。于是又在网上找了一个新的转一般UTF-8的函数。代码如下:
function UTF8ToAnsiString(utf8str:string; CodePage: integer):AnsiString;

var

 i:integer;

 buffer:widestring;

 ch,c1,c2:byte;



begin

 result:='';

 i:=1;

 while i<=Length(utf8str) do begin

   ch:=byte(utf8str[i]);

   setlength(buffer,length(buffer)+1);

   if (ch and $80)=0 then //1-byte

      buffer[length(buffer)]:=widechar(ch)

   else begin

   if (ch AND $E0) = $C0 then begin // 2-byte

      inc(i);

      c1 := byte(utf8str[i]);

      buffer[length(buffer)]:=widechar((word(ch AND $1F) SHL 6) OR (c1 AND $3F));

    end

    else begin // 3-byte

      inc(i);

      c1 := byte(utf8str[i]);

      inc(i);

      c2 := byte(utf8str[i]);

      buffer[length(buffer)]:=widechar(

        (word(ch AND $0F) SHL 12) OR

        (word(c1 AND $3F) SHL 6) OR

        (c2 AND $3F));

    end;

    end;

   inc(i);

  end; //while

  i := WideCharToMultiByte(codePage,

           WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,

           @buffer[1], -1, nil, 0, nil, nil);

  if i>1 then begin

    SetLength(Result, i-1);

    WideCharToMultiByte(codePage,

        WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,

        @buffer[1], -1, @Result[1], i-1, nil, nil);

  end;

end;
可见,其中调用了WideCharToMultiByte。WideCharToMultiByte的详细讲解可以参考下面这篇文章:
MultiByteToWideChar和WideCharToMultiByte用法详解 
 
 
//======================================================================== //TITLE: //    MultiByteToWideChar和WideCharToMultiByte用法详解 //AUTHOR: //    norains //DATE: //    第一版:Monday  25-December -2006 //    增补版:Wednesday 27-December -2006 //    修订版:Wednesday 14-March-2007 (修正之前的错误例子) //Environment: //  EVC4.0 + Standard SDK //========================================================================   1.使用方法详解   在本文开始之处,先简要地说一下何为短字符和宽字符.   所谓的短字符,就是用8bit来表示的字符,典型的应用是ASCII码.而宽字符,顾名思义,就是用16bit表示的字符,典型的有UNICODE.关于windows下的ASCII和UNICODE的更多信息,可以参考这两本经典著作:《windows 程序设计》,《windows 核心编程》.这两本书关于这两种字符都有比较详细的解说.     宽字符转换为多个短字符是一个难点,不过我们只要掌握到其中的要领,便可如鱼得水.   好吧,那就让我们开始吧.     这个是我们需要转化的多字节字符串:     char sText[20] = {"多字节字符串!OK!"};     我们需要知道转化后的宽字符需要多少个数组空间.虽然在这个里程里面,我们可以直接定义一个20*2宽字符的数组,并且事实上将运行得非常轻松愉快.但假如多字节字符串更多,达到上千个乃至上万个,我们将会发现其中浪费的内存将会越来越多.所以以多字节字符的个数的两倍作为宽字符数组下标的声明绝对不是一个好主意.   所幸,我们能够确知所需要的数组空间.   我们只需要将MultiByteToWideChar()的第四个形参设为-1,即可返回所需的短字符数组空间的个数:   DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, sText, -1, NULL, 0);     接下来,我们只需要分配响应的数组空间:   wchar_t *pwText;   pwText = new wchar_t[dwNum];   if(!pwText)   {    delete []pwText;   }     接着,我们就可以着手进行转换了.在这里以转换成ASCII码做为例子:   MultiByteToWideChar (CP_ACP, 0, psText, -1, sText, dwSize);     最后,使用完毕当然要记得释放占用的内存:   delete []psText;       同理,宽字符转为多字节字符的代码如下:     wchar_t wText[20] = {L"宽字符转换实例!OK!"};   DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE);   char *psText;   psText = new char[dwNum];   if(!psText)   {    delete []psText;   }   WideCharToMultiByte (CP_OEMCP,NULL,lpcwszStr,-1,psText,dwNum,NULL,FALSE);   delete []psText;      如果之前我们已经分配好空间,并且由于字符串较短,可以不理会浪费的空间,仅仅只是想简单地将短字符和宽字符相互转换,那有没有什么简便的方法呢?    WIN32 API里没有符合这种要求的函数,但我们可以自己进行封装:         //-------------------------------------------------------------------------------------   //Description:   // This function maps a character string to a wide-character (Unicode) string   //   //Parameters:   // lpcszStr: [in] Pointer to the character string to be converted   // lpwszStr: [out] Pointer to a buffer that receives the translated string.   // dwSize: [in] Size of the buffer   //   //Return Values:   // TRUE: Succeed   // FALSE: Failed   //   //Example:   // MByteToWChar(szA,szW,sizeof(szW)/sizeof(szW[0]));   //---------------------------------------------------------------------------------------   BOOL MByteToWChar(LPCSTR lpcszStr, LPWSTR lpwszStr, DWORD dwSize)   {     // Get the required size of the buffer that receives the Unicode     // string.     DWORD dwMinSize;     dwMinSize = MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, NULL, 0);       if(dwSize < dwMinSize)     {      return FALSE;     }            // Convert headers from ASCII to Unicode.     MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, lpwszStr, dwMinSize);       return TRUE;   }     //-------------------------------------------------------------------------------------   //Description:   // This function maps a wide-character string to a new character string   //   //Parameters:   // lpcwszStr: [in] Pointer to the character string to be converted   // lpszStr: [out] Pointer to a buffer that receives the translated string.   // dwSize: [in] Size of the buffer   //   //Return Values:   // TRUE: Succeed   // FALSE: Failed   //   //Example:   // MByteToWChar(szW,szA,sizeof(szA)/sizeof(szA[0]));   //---------------------------------------------------------------------------------------   BOOL WCharToMByte(LPCWSTR lpcwszStr, LPSTR lpszStr, DWORD dwSize)   {    DWORD dwMinSize;    dwMinSize = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE);    if(dwSize < dwMinSize)    {     return FALSE;    }    WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,lpszStr,dwSize,NULL,FALSE);    return TRUE;   }       使用方法也很简单,示例如下:   wchar_t wText[10] = {L"函数示例"};   char sText[20]= {0};   WCharToMByte(wText,sText,sizeof(sText)/sizeof(sText[0]));   MByteToWChar(sText,wText,sizeof(wText)/sizeof(wText[0]));     这两个函数的缺点在于无法动态分配内存,在转换很长的字符串时可能会浪费较多内存空间;优点是,在不考虑浪费空间的情况下转换较短字符串非常方便.   2.MultiByteToWideChar()函数乱码的问题   有的朋友可能已经发现,在标准的WinCE4.2或WinCE5.0 SDK模拟器下,这个函数都无法正常工作,其转换之后的字符全是乱码.及时更改MultiByteToWideChar()参数也依然如此.   不过这个不是代码问题,其结症在于所定制的操作系统.如果我们定制的操作系统默认语言不是中文,也会出现这种情况.由于标准的SDK默认语言为英文,所以肯定会出现这个问题.而这个问题的解决,不能在简单地更改控制面板的"区域选项"的"默认语言",而是要在系统定制的时候,选择默认语言为"中文".   系统定制时选择默认语言的位置于:   Platform -> Setting... -> locale -> default language ,选择"中文",然后编译即可.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Delphi是一种编程语言,而Delphixe是对Delphi进行了扩展和改进的版本。utf8是一种常用的字符编码方式,它可以表示世界上几乎所有的字符,并且在互联网上广泛应用。 在Delphixe,解析utf8的方式可以通过使用相关的库和函数来实现。首先,我们需要在程序引入相关的单元,例如使用System.SysUtils和System.Classes单元。然后,我们可以使用TStreamReader类来读取包含utf8编码文本的文件,TStringStream类来处理字符串数据,以及TIdDecoder类来解码Base64编码的utf8字符串。 通过TStreamReader类的构造函数以及TStringStream类的LoadFromStream方法可以将utf8的文本数据读取到程序。如果需要解码Base64编码的utf8字符串,可以使用TIdDecoder类的DecodeBytesToStream方法将其解码为TStream类型。在解码完成后,我们可以通过读取TStringStream的字符串数据,或者将其输出到需要的位置。 比如,下面是一个简单的示例,演示了如何使用Delphixe解析utf8编码的文本文件: ``` uses System.SysUtils, System.Classes; var StreamReader: TStreamReader; Content: TStringList; begin // 创建TStreamReader对象 StreamReader := TStreamReader.Create('file.utf8'); try // 创建TStringList对象用于保存内容 Content := TStringList.Create; try // 通过TStreamReader将utf8文本读取到TStringList Content.LoadFromStream(StreamReader.BaseStream, TEncoding.UTF8); // 输出内容 Writeln(Content.Text); finally // 释放TStringList对象 Content.Free; end; finally // 释放TStreamReader对象 StreamReader.Free; end; end. ``` 通过以上代码,我们可以读取名为file.utf8的utf8编码文本文件,并将其内容输出到控制台。当然,在实际应用,我们可以根据需求,对读取到的utf8文本进行进一步的处理和解析。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值