现在的位置: 首页 > 综合 > 正文

文本编码格式转换问题[整理帖]

2013年09月08日 ⁄ 综合 ⁄ 共 3187字 ⁄ 字号 评论关闭
 这几天正好遇到这个问题,需要看日文文档,但是在中文环境下是乱码,总是切换语言环境也太麻烦了,干脆想了这个办法,自己写一个转换编码格式的小软件,当然很多技术难点是在csdn找到的,我只是照葫芦画瓢罢了

代码作者:

linzhengqun(风。我回来了)

下面是相关源码:

1.实现任意多字节语言与Unicode的转换:  
  function   UnicodeEncode(Str:   string;   CodePage:   integer):   WideString;  
  var  
      Len:   integer;  
  begin  
      Len   :=   Length(Str)   +   1;  
      SetLength(Result,   Len);  
      Len   :=   MultiByteToWideChar(CodePage,   0,   PChar(Str),   -1,   PWideChar(Result),   Len);  
      SetLength(Result,   Len   -   1);   //end   is   #0  
  end;  
   
  function   UnicodeDecode(Str:   WideString;   CodePage:   integer):   string;  
  var  
      Len:   integer;  
  begin  
      Len   :=   Length(Str)   *   2   +   1;   //one   for   #0  
      SetLength(Result,   Len);  
      Len   :=   WideCharToMultiByte(CodePage,   0,   PWideChar(Str),   -1,   PChar(Result),   Len,   nil,   nil);  
      SetLength(Result,   Len   -   1);  
  end;  
   
  比如,GB2312的代码页是936,则GB2312要转为Unicode可以这样:  
  UniStr   :=   UnicodeEncode(GBStr,   936);  
  要从Unicode内码转为GB2312则可以这样:  
  GBStr   :=   UnicodeDecode(UniStr,   936);  
  对于其他语言也是一样,只要知道了代码页。
注:日文的代码页是932

2.文件的编码变换
首先看这位大侠的几个提示:

  AnsiToUTF8
  UTF8ToUnicode
  看一下这两个函数的帮助。

  你可以用一个TStringList将文本文件Load进来,然后声明一个WideString变量,最后调用上面的StringToWideChar,转换后的信息保存在WideString中。
  再声明一个MemoryStream将WideString写进流中。
  最后将流保存为一个文本文件。
                                                                                                                                                                          
  你去文件文件看,它就是Unicode编码的,且信息一样。

下面是终极版:
每一种格式的文本在最开头都会有一个标识,标识它是什么编码。比如Unicode的最开头就是FFFE。笔记本就 是根据最开头的这个标识来识别它是什么码的。
                                                                                                                                                                                                 
  而你在上面写的时候,没有将这个标识写在文件的最开头,所以你用笔记本打开的时候识别不了,不信你打开之后选另存为,就可以看到它识别为Ansi码了,所以会显示不对。
                                                                                                                                                                                                 
  正确的做法是在文件的开头写进FFFE这个标识,就可以正确显示了。
                                                                                                                                                                                                 
  下面是源码:
  var   SL:   TStringList;   
          MM:   TMemoryStream; 
          AnStr:   String;
          WS:   WideString; 
          P:   PByteArray; 
  begin
      SL:=   TStringList.Create;   
      MM:=   TMemoryStream.Create;
      try 
          SL.LoadFromFile('test.txt'); 
          AnStr:=   SL.Text; 
          WS:=   AnStr;                 //转为Unicode 
          
          //文本开头写进Unicode的标识 
          GetMem(P,   2   *   Sizeof(Char));
          P[0]:=   $FF;
          P[1]:=   $FE;
          MM.Write(P^,   2   *   Sizeof(Char)); 
          
          //将Unicode文本写进流中保存。
          MM.Write(PWideChar(WS)^,   Length(WS)   *   Sizeof(WideChar));
          MM.SaveToFile('test2.txt');  
          
          FreeMem(P); 
      finally 
          SL.Free; 
          MM.Free;
      end;
  end;
  
  我先在一个笔记本中写下:“yes是的,这是Unicode”,然后保存为Test文件。这个时候它是Ansi编码。         
  执行我上面的代码之后,文本保存为Test2,这时它就是Unicode码了,可以正确显示,你可选另存为看看它是不是Unicode编码。                                                                                                                                                                 

然后还有另外一个哥们的发言:

warmworm(warmworm)

厚厚  
  以前我也为ansi和unicode的转换,看遍了这些函数,其实最简单的方法  
   
  就是  
  Ansi->Unicode        
        strUnicode   :=   WideString(strAnsi);  
   
  Unicode->Ansi  
        strAnsi   :=   AnsiString(strUnicode);

另一个帖子中:

aiirii(ari-http://spaces.msn.com/members/aiirii/)

  unicode文本文件:头两个字符分别是FF   FE(16进制)  
  unicode   big   endian文本文件:头两个字符分别是FE   FF(16进制,big   endian自然会是相反的)  
   
  utf-8文本文件:头两个字符分别是EF   BB(16进制)  (补充:如果想通过写入文件头来标识utf-8编码文件,则需要写入Write(LogFile,#$EF#$BB#$BF);)
   
  可以用记事本打开一个文本文件,以各种方式另存为,再用16进制编辑器就可以看到了。

抱歉!评论已关闭.