把string强制转成widestring的时候,当string里面的数据不巧为一些特殊数据时,widestring会把它转换成其他字符,造成数据丢失,请问怎么解决?var S:string;
   WS:widestring;
begin
   s:=#2+#3+#0+#10+#0+#1+#164+#59;
   showmessage(inttostr(Length(S)));
   WS:=widestring(S);
   S:=WS;
   showmessage(inttostr(Length(S)));
end;第一个得出的长度是8
第二个得出的长度就变成7了
请问怎么才能使数据不丢失?
做项目的时候,widestring是接口,但是由于处理的数据都是16进制的,所以我在内部都转成string或者array of byte,最后的时候才转换一下。。没想到还是出这种问题..

解决方案 »

  1.   

    s:=#2+#3+#0+#10+#0+#1+#164+#59;
    因为#164>#128,所以转换到#164时它判断在A0~FE,所以它认为下个字符应该是在40~FE,
    但它发现它是#59不符合编码规则便把#164转化为ANSI#63.
    你试着:
    s:=#2+#3+#0+#10+#0+#1+#164+#64
    s:=#2+#3+#0+#10+#0+#1+#236+#164+#59;
    GBK编码
    其第一字节的值在 16 进制的 81~FE 之间,第二字节在 40~FE
      

  2.   

    我也知道是这个原因,但是有没有办法在转成widestring的时候不作这种判断?
      

  3.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
    implementation{$R *.dfm}var    len:integer;function GetWideString(Const s:string):WideString;
    var i:integer;
        u4str:UCS4String;
    begin
        len:=Length(S);
        SetLength(u4str,len+1);
        for i:=1 to  len do
        begin
            u4str[i-1]:=UCS4Char(S[i]);
        end;
        u4str[len]:= UCS4Char(#0);
        Result:=UCS4StringToWideString(u4str);
    end;function GetString(Const WideStr:WideString):String;
    var u4str:UCS4String;
        i:integer;
        s:string;
    begin
        setlength(u4str,len+1);
        SetLength(s,len);
        u4str:=WideStringToUCS4String(WideStr);
        for i:=1 to  len do
        begin
            s[i]:=char(u4str[i-1]);
        end;
        Result:=s;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var StrInput:string;
        StrOutput:string;
        WideStr:widestring;
    begin
       StrInput:=#2+#3+#0+#10+#0+#1+#164+#59;   WideStr:= GetWideString(StrInput); //转为widestring   StrOutput:=GetString(WideStr); //转为string   if StrInput=StrOutput then
           showmessage('ok');
    end;end.
      

  4.   

    回复人: hellolongbin(一个人[终不似 少年游]) ( ) 信誉:106  2005-09-20 12:33:00  得分: 0  
     
     
       我想先知道楼主信誉为何如此之低他的贴子是都结了啊,奇怪了
     
      

  5.   

    确实可以~~可是真奇怪。。为啥不能直接转,非要从UCS4String那里转一圈。。其实上午已经想到照上面的思路了,作了一遍,就是因为没有想到UCS4String才失败了。。
      

  6.   

    To struggle813(深蓝大道):有几年因为读书,没上来过,当中不知道发生了什么事,反正最近因为工作原因又上来的时候就是这个样子了
      

  7.   

    回复人: yuechuan(yuechuan) ( ) 信誉:71  2005-09-20 12:55:00  得分: 0  
     
     
       老实说我也不知道帖子都结掉的啊~~
      
     
    诚实,呵呵,是CSDN管理出问题了吗
      

  8.   

    结掉了,不过还是想问一下,为啥非要从UCS4String这里转一圈?
    老实说本来一个字节的东东,先拉长成4个字节,再缩小到2个字节。。看上去真的很不爽啊。。
      

  9.   

    照楼上的方法,自己也写了一个,这个觉得更加好点,不用从UCS4String那里转一圈var S,S2:string;
       I: Integer;
       WS:widestring;
    begin
       s:=#2+#3+#0+#10+#0+#1+#164+#59;
     //  showmessage(inttostr(Length(S)));
     setlength(WS,Length(S));
     for I := 1  to  length(S) do    // Iterate
       begin
         WS[I]:= widechar(S[I]);
       end;    // for   showmessage(inttostr(Length(WS)));   setlength(S2,Length(WS));
       for I := 1  to  length(S) do    // Iterate
       begin
         S2[I]:= char(WS[I]);
       end;    // for
       showmessage(inttostr(Length(S2)));   if S=S2 then showmessage('OK');