string和widestring转换丢失数据的问题

yuechuan 2005-09-20 09:30:53
把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,最后的时候才转换一下。。没想到还是出这种问题..
...全文
680 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuechuan 2005-09-20
  • 打赏
  • 举报
回复
老实说我也不知道。。。帖子都结掉的啊~~
hellolongbin 2005-09-20
  • 打赏
  • 举报
回复
我想先知道楼主信誉为何如此之低
yuechuan 2005-09-20
  • 打赏
  • 举报
回复
继续顶。。
yuechuan 2005-09-20
  • 打赏
  • 举报
回复
再顶~~
yuechuan 2005-09-20
  • 打赏
  • 举报
回复
在线求解~~~
yuechuan 2005-09-20
  • 打赏
  • 举报
回复
照楼上的方法,自己也写了一个,这个觉得更加好点,不用从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');
yuechuan 2005-09-20
  • 打赏
  • 举报
回复
结掉了,不过还是想问一下,为啥非要从UCS4String这里转一圈?
老实说本来一个字节的东东,先拉长成4个字节,再缩小到2个字节。。看上去真的很不爽啊。。
struggle813 2005-09-20
  • 打赏
  • 举报
回复
回复人: yuechuan(yuechuan) ( ) 信誉:71 2005-09-20 12:55:00 得分: 0


老实说我也不知道。。。帖子都结掉的啊~~


诚实,呵呵,是CSDN管理出问题了吗
yuechuan 2005-09-20
  • 打赏
  • 举报
回复
To struggle813(深蓝大道):有几年因为读书,没上来过,当中不知道发生了什么事,反正最近因为工作原因又上来的时候就是这个样子了。。。
yuechuan 2005-09-20
  • 打赏
  • 举报
回复
确实可以~~可是真奇怪。。为啥不能直接转,非要从UCS4String那里转一圈。。其实上午已经想到照上面的思路了,作了一遍,就是因为没有想到UCS4String才失败了。。
struggle813 2005-09-20
  • 打赏
  • 举报
回复
回复人: hellolongbin(一个人[终不似 少年游]) ( ) 信誉:106 2005-09-20 12:33:00 得分: 0


我想先知道楼主信誉为何如此之低

他的贴子是都结了啊,奇怪了

struggle813 2005-09-20
  • 打赏
  • 举报
回复
unit Unit1;

interface

uses
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.
struggle813 2005-09-20
  • 打赏
  • 举报
回复
我写个函数给你
yuechuan 2005-09-20
  • 打赏
  • 举报
回复
那怎么弄呢?
struggle813 2005-09-20
  • 打赏
  • 举报
回复
可以的
herman~~ 2005-09-20
  • 打赏
  • 举报
回复
楼上的强,学习

yuechuan 2005-09-20
  • 打赏
  • 举报
回复
我也知道是这个原因,但是有没有办法在转成widestring的时候不作这种判断?
struggle813 2005-09-20
  • 打赏
  • 举报
回复
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

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧