将AnsiString转换成Unicode字符串 [英] Converting an AnsiString to a Unicode String

查看:493
本文介绍了将AnsiString转换成Unicode字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将D2006程序转换为D2010。我有一个值存储在我的数据库中每个字符串的单个字节,我需要将它加载到一个具有LoadFromStream的控件,所以我的计划是将字符串写入一个流,并使用LoadFromStream。但它没有奏效。在研究问题时,我看到一个问题,告诉我,我不太明白如何从AnsiString转换为Unicode字符串的工作原理。这是一个独立的代码,说明了我被以下问题所困惑的问题:

  procedure TForm1.Button1Click(Sender:TObject) ; {$ O-} 
var
sBuffer:String;
oStringStream:TStringStream;
sAnsiString:AnsiString;
sUnicodeString:String;
iSize1,
iSize2:Word;
begin
sAnsiString:='12345';
oStringStream:= TStringStream.Create(sBuffer);
sUnicodeString:= sAnsiString;
iSize1:= StringElementSize(sAnsiString);
iSize2:= StringElementSize(sUnicodeString);
oStringStream.WriteString(sUnicodeString);
结束

如果你在最后一行打破,检查oStringStream的Bytes属性,你会看到它看起来像这样:

 字节(49 {$ 31},50 {$ 32},51 {$ 33},52 {$ 34} 53 {$ 35} 

我期待看起来像

 (49 {$ 31},00 {$ 00},50 {$ 32},00 {$ 00},51 {$ 33},00 {$ 00},
52 {$ 34},00 {$ 00},53 {$ 35},00 {$ 00} ...

显然我的期望是错误的,但是如何将AnsiString转换为unicode?

我没有从LoadFromStream获得正确的结果,因为它是从流中读取两个字节的数据,但是接收的数据不是这样排列的,为什么要根据unicode字符串给LoadFromStream一个格式正确的数据流做什么?



感谢您的帮助。

解决方案

什么是oStringStream.WriteString的参数的类型?如果是AnsiString,您将从Unicode转换为Ansi,并解释您的示例。






更新:现在真正的问题是TStringStream如何在内部存储数据。
在以下代码示例(Delphi 2009)中

  procedure TForm1.Button1Click(Sender:TObject); 
var
S:string;
SS:TStringStream;

begin
S:='asdfg';
SS:= TStringStream.Create(S); //每个char 1个字节
SS.WriteString('321');
Label1.Caption:= SS.DataString;
SS.Free;
结束

TStringStream内部使用默认系统ANSI编码(每个字符1个字节)。
构造函数和WriteString过程将一个字符串参数从unicode转换为ANSI。



要覆盖此行为,必须在构造函数中明确声明编码:

  procedure TForm1.Button1Click(Sender:TObject); 
var
S:string;
SS:TStringStream;

begin
S:='asdfg';
SS:= TStringStream.Create(S,TEncoding.Unicode); //每字节2个字节
SS.WriteString('321');
Label1.Caption:= SS.DataString;
SS.Free;
结束


I'm converting a D2006 program to D2010. I have a value stored in a single byte per character string in my database and I need to load it into a control that has a LoadFromStream, so my plan was to write the string to a stream and use that with LoadFromStream. But it did not work. In studying the problem, I see an issue that tells me that I don't really understand how conversion from AnsiString to Unicode string works. Here is a piece of standalone code that illustrates the issue I am confused by:;

procedure TForm1.Button1Click(Sender: TObject); {$O-}
var
  sBuffer: String;
  oStringStream: TStringStream;
  sAnsiString: AnsiString;
  sUnicodeString: String;
  iSize1,
  iSize2: Word;
begin
  sAnsiString := '12345';
  oStringStream := TStringStream.Create(sBuffer);
  sUnicodeString := sAnsiString;
  iSize1 := StringElementSize(sAnsiString);
  iSize2 := StringElementSize(sUnicodeString);
  oStringStream.WriteString(sUnicodeString);
end;

If you break on the last line, and inspect the Bytes property of oStringStream, you will see that it looks like this:

Bytes (49 {$31}, 50 {$32}, 51 {$33}, 52 {$34}, 53 {$35}

I was expecting that it might look something like

(49 {$31}, 00 {$00}, 50 {$32}, 00 {$00}, 51 {$33}, 00 {$00}, 
 52 {$34}, 00 {$00}, 53 {$35}, 00 {$00} ...

Apparently my expectations are in error. But then, how to convert an AnsiString to unicode?

I'm not getting the right results out of the LoadFromStream because it is reading from the stream two bytes at a time, but the data it is receiving is not arranged that way. What is it that I should do to give the LoadFromStream a well formed stream of data based on a unicode string?

Thank you for your help.

解决方案

What is the type of the oStringStream.WriteString's parameter? If it is AnsiString, you have an implicit conversion from Unicode to Ansi and that explains your example.


Updated: Now the real question is how TStringStream stores data internally. In the following code sample (Delphi 2009)

procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;
  SS: TStringStream;

begin
  S:= 'asdfg';
  SS:= TStringStream.Create(S);  // 1 byte per char
  SS.WriteString('321');
  Label1.Caption:= SS.DataString;
  SS.Free;
end;

TStringStream uses internally the default system ANSI encoding (1 byte per char). The constructor and WriteString procedures convert a string argument from unicode to ANSI.

To override this behaviour you must declare the encoding explicitely in the constructor:

procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;
  SS: TStringStream;

begin
  S:= 'asdfg';
  SS:= TStringStream.Create(S, TEncoding.Unicode);  // 2 bytes per char
  SS.WriteString('321');
  Label1.Caption:= SS.DataString;
  SS.Free;
end;

这篇关于将AnsiString转换成Unicode字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆