我在用Delphi做一个项目,其中用到一个Unicode文本,要其中含中文的行,转化为GB2312。
文件下载: http://www.chrsoft.com/download/UnicodeTExt.rar
在该文件中,第一行的第一段是索引,根据索引我知道那一行是不是中文,但:
1。我有第一段的ANSI的字符串,要找出第一段是相应UNICODE码的那个字符串的行
2。找到后,把那一行转化为GB2312,并做进一步处理。
我的做法:
把文件读到流中,去掉最前面的FFFE,然后做 unicode2GB2312的操作
结果:
乱码。
有给出解决方案的,我付出我的所有分.
文件下载: http://www.chrsoft.com/download/UnicodeTExt.rar
在该文件中,第一行的第一段是索引,根据索引我知道那一行是不是中文,但:
1。我有第一段的ANSI的字符串,要找出第一段是相应UNICODE码的那个字符串的行
2。找到后,把那一行转化为GB2312,并做进一步处理。
我的做法:
把文件读到流中,去掉最前面的FFFE,然后做 unicode2GB2312的操作
结果:
乱码。
有给出解决方案的,我付出我的所有分.
然后用我自己写的一个函数将UNICODE的“你好”转成普通字符为:4F60597D,(正好高位低位反了反,这个好处理),感觉用我的程序将其读入(得到的是WideString),直接赋给AnsiString应该就可以了,这两个函数:{$IFDEF UNICODE}
function EncodeWideString(Value:WideString):String;
//encode the widestring to saveable string
//2003.03.04
var
I:Integer;
begin
Result:='';
for I:=1 to Length(Value) do begin
Result:=Result+IntToHex(WORD(Value[I]) shr 8,2);
Result:=Result+IntToHex(WORD(Value[I]) and $00ff,2);
end;
end;function DecodeWideString(Value:String):WideString;
//decode the string to widestring
//2003.03.04
var
I:Integer;
begin
Result:='';
for I:=0 to (Length(Value) div 4)-1 do begin
Result:=Result+WChar(StrToInt('$'+Value[I*4+1]+Value[I*4+2]) shl 8
+ StrToInt('$'+Value[I*4+3]+Value[I*4+4]));
end;
end;
{$ENDIF}另,以上两个函数做成的UNICODE转换程序可以到:
http://www.tonixsoft.com/component/tlmpack/utlmpack_Delphi.exe
下载。
把Unicode编码文本读入内存然后对文件里面的Unicode字符进行判断如果为GB2312编码的 则保存在一个字符串中输出字符串
var
SourceLength : integer;
DoneLength : integer;
AscNo : integer;
Byte1, Byte2, Byte3: integer;
GbStr : string;
begin
GbStr := '';
if Trim(unicodestr) = '' then
exit; SourceLength := Length(UnicodeStr);
DoneLength := 1; repeat
AscNo := ord(UnicodeStr[DoneLength]);
case (AscNo and $E0) of
$E0:
begin
Byte1 := (AscNo and $0F) shl 12;
Inc(DoneLength);
if DoneLength > SourceLength then
break;
AscNo := ord(UnicodeStr[DoneLength]);
Byte2 := (AscNo and $3F) shl 6;
Inc(DoneLength);
if DoneLength > SourceLength then
break;
AscNo := ord(UnicodeStr[DoneLength]);
Byte3 := AscNo and $3F;
end;
$C0:
begin
Byte1 := (AscNo and $1F) shl 6;
Inc(DoneLength);
if DoneLength > SourceLength then
break;
AscNo := ord(UnicodeStr[DoneLength]);
Byte2 := (AscNo and $3F);
Byte3 := 0;
end;
0..$BF:
begin
Byte1 := AscNo;
Byte2 := 0;
Byte3 := 0;
end;
end; //case;
GbStr := GBStr + widechar(Byte1 + Byte2 + Byte3);
Inc(DoneLength);
if DoneLength > SourceLength then
break;
until DoneLength >= SourceLength;
result := GbStr;end; s := unicode2gb(SourceStr);
我看了tonylk的资料,虽然没能直接用来解决问题,但在看的时候触发我的灵感:原来我的问题不在于不会转化,而在于没有做好Delphi的内存管理!
研究了相关资料后,问题就解决了。
S.F. 的转码的方法应该是好的,有利于提高效率,但我觉得在我的项目上这点效果不明显。所以先收着,下次再用到时,好好测试一下,就能大发神威了。
因为都不是完整的解决方案,所以我就不会给出我的所有了。
就此结帖。
表示你的这是一个Small Endian的unicode文本,它和x86处理器上面的unicode正好相反,需要交换每个word的高字和低字才行,交换完了用一个string(xxxx) 就成了gb2312了