散分咯:如何用DELPHI将文本文件中的GB13000 UCS-2编码文本转换为GBK并读取出来?--自己解决,愿与大家分享(200分)

  • 主题发起人 主题发起人 lyj.hm
  • 开始时间 开始时间
L

lyj.hm

Unregistered / Unconfirmed
GUEST, unregistred user!
如何将一个文本文件中的GB13000 UCS-2编码的文本信息转换为GBK的文本并显示出来?有现成的函数可以使用吗?另外希望能够比较详细解释一下为什么这么编写?谢谢.
 
procedure TForm1.Button1Click(Sender: TObject);
var
s:string;
s1:string;
begin
s:='汉';
s1:=ansitoutf8(s);
showmessage(inttohex(ord(s1[1]),2)+' '+inttohex(ord(s1[2]),2)+' '+inttohex(ord(s1[3]),2)+' ');
//得到 E6 B1 89。
end;
procedure TForm1.Button1Click(Sender: TObject);
var
s:string;
s1:string;
begin
s:=chr($E6)+chr($B1)+chr($89);
s1:=utf8toansi(s);
showmessage(s1);
//得到 E6 B1 89。

end;
 
有自带的编码转换控件,也可以自已写个函数来解决这个问题
 
是区码和位码的关系吗?
 
GB13000 UCS-2编码等同于Unicode标准的UTF-16编码格式。如果是存储在文本文件中的话,就是UTF-16编码格式字节序列。想要把UTF-16编码机制的文本文件读取到你的程序里面的话,可以用我前两个星期在论坛上公布的一个处理Unicode编码的DLL--
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3533788
来实现。

具体地来说,你先要用该DLL里面的一个LoadUniByteSequFromFile函数把文本文件的内容读取到你程序的一个字节序列里面去,此时你的程序得到的就是UTF-16编码格式字节序列。接下来用BSToCUSForUTF16函数把UTF-16编码格式字节序列转换为UTF-16字符串(也就是WideString字符串)。最后用API函数WideCharToMultiByte把WideString字符串转换为GBK编码的字符串(GBK编码的代码页是936)。
 
最后解答:
首先要说明的是GB-13000是中国的编码标准,与UNICODE兼容,我就把它理解为就是中国的UNICODE(也许不对,呵呵)。而UCS-2也就是双字节编码。用两个字节16位表示一个字符。那么对于这种编码我觉得只需要注意的是:这种编码的高8位在后面,而低8位在前面。这对转换相当重要。你可以理解为外国人(比如美国),名在前面而姓在后面。我打这个比喻就是让你想象中国人的姓名称呼习惯。呵呵,姓前而名在后。这也是GBK的编码方式了。见下面了。

而GBK就是中国自己的标准了。它是GB2312的一个扩展,并和GB2312兼容。也就是GB2312的升级版本。就好象INTEL的处理器,P3到P4,升级了,但还是奔腾,只是容量更大了而已。GBK也是比GB2312含有更多的字符。现在WINDOW支持的是GBK。而比如IE内的编码写的是GB2312,我的理解是可能只支持常用的字符。要么其实系统用GBK来解释,我没有验证!
罗嗦的很,SORRY。转入正题。

现在要转换GB13000为GBK。其实简单点说,都是双字节编码格式,唯一的区别就是高第字节的位置不一样而已。那么我们要做的工作就是把这两个东东换个地方就可以了。下面开始手术,嘿嘿(其实我讨厌上医院,好贵!)

1:获取包含GB13000编码的文本文件。
2:把文件读入缓存。
3:把缓存中的数据转换为序数(这步对理解很关键,本来是编码,编程了序数,那不就是成了一堆纯粹的二进制的0和1了吗?先恢复本来面目,再重新编码,就是这么回事了)
4:每两个字节为单位读取。一个个字节的读。
5:将后读的字节(高位)*256加先读出的字节(低位),不就重新组合了吗?
6:用WideChar()可以重新编码成GBK了。完毕

具体的代码如下:大家自己去研究一下:

iFileHandle := FileOpen(ExtractFilePath(Application.ExeName) + 'wz.txt', fmOpenRead); // 打开文件并获取句柄
iFileLength := FileSeek(iFileHandle,0,2); //通过定位到文件尾部来获得文件的长度
FileSeek(iFileHandle,0,0); //重新定位到文件开头部分准备读取
Buffer := PChar(AllocMem(iFileLength + 1)); //分配内存空间准备存放要从WZ.TXT中的信息
iBytesRead := FileRead(iFileHandle, Buffer^, iFileLength); //将信息读入分配的缓存中并返回真实的字节数

FileClose(iFileHandle); //关闭打开的文件

i:=0;

Memo1.lines.clear;
while (i <= iBytesRead - 1) do
begin
ordChar := Ord(Buffer[i + 1]) * 256 + Ord(Buffer); // 通过从内存获取内码,转换为序数并合并高低字节.*256就是将低8位变成高8位
readString := readString + widechar(ordChar); //使用wideChar函数就可以显示宽字符了.即显示出汉字.


如果大家还有不懂的,愿意一起交流,共同提高。我的QQ是:602027784
 
多人接受答案了。
 

Similar threads

回复
0
查看
1K
不得闲
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部