将 AnsiString 转换为 Unicode 字符串

发布于 2024-08-27 07:17:52 字数 1164 浏览 5 评论 0原文

我正在将 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);
end;

如果您在最后一行中断,并检查 oStringStream 的 Bytes 属性,您将看到它看起来像这样:

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 中获得正确的结果,因为它一次从流中读取两个字节,但它接收的数据并不是这样排列的。我应该做什么才能为 LoadFromStream 提供基于 unicode 字符串的格式良好的数据流?

感谢您的帮助。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

朱染 2024-09-03 07:17:52

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);  // 1 byte per char
  SS.WriteString('321');
  Label1.Caption:= SS.DataString;
  SS.Free;
end;

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 bytes per char
  SS.WriteString('321');
  Label1.Caption:= SS.DataString;
  SS.Free;
end;

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;
む无字情书 2024-09-03 07:17:52

在 Delphi 最新版本中,您可以使用 TEncoding:

TEncoding.UTF8.GetString(TEncoding.ANSI.GetBytes(MyString))

In Delphi last versions you could use TEncoding:

TEncoding.UTF8.GetString(TEncoding.ANSI.GetBytes(MyString))
怂人 2024-09-03 07:17:52

我想你想使用:

LoadFromStream(stream, TEncoding.ASCII);

如果你的单字节文本不是 ASCII 而是基于代码页,那么这可能有效:

LoadFromStream(stream, TEncoding.GetEncoding(1252));

其中“1252”是你的单字节文本所基于的代码页。

I think you want to use:

LoadFromStream(stream, TEncoding.ASCII);

If your single byte text is not ASCII but is based on a code page, then this might work:

LoadFromStream(stream, TEncoding.GetEncoding(1252));

where the "1252" is the code page that your single byte text is based on.

◇流星雨 2024-09-03 07:17:52

流格式很大程度上取决于 TStringStream.Encoding。在您的示例中,使用的代码页应与 sBuffer 相同(请参阅 TStringStream.Create 的实现)。

由于 oStringStream.WriteString(sUnicodeStream); 似乎保存为单个字节,因此我假设 sBuffer 是 Ansistring 或 RawByteString。

现在...为什么读取失败...您尚未向我们提供如何在该流中读回的示例。

The stream format largely depends on the TStringStream.Encoding. In your exemple, the used codepage should be the same as sBuffer (See implentation from TStringStream.Create).

Since oStringStream.WriteString(sUnicodeStream); seems to save as single bytes, I'd assume sBuffer is an Ansistring or a RawByteString.

Now... why do the reading fails... You have yet to supply us an example of how you do read back in that stream.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文