delphi - 将以null结尾的内存流转换为unicode字符串

标签 delphi memorystream unicode-string null-terminated

在Delphi XE中,我正在从剪贴板中捕获CF_UNICODETEXT数据。结果是以两个空字节终止的流。要获取复制到剪贴板的实际字符串,我需要去除空值。

This similar so question包含一种从TMemoryStream转换为Delphi的unicode字符串的好方法:

function MemoryStreamToString(M: TMemoryStream): string;
begin
  SetString(Result, M.Memory, M.Size div SizeOf(Char));
end;


但是,就我而言,这将产生一个包含尾随null的字符串。我可以通过限制大小来解决此问题:

function ClipboardMemoryStreamToString(M: TMemoryStream): string;
begin
  SetString(Result, M.Memory, (M.Size - SizeOf(Char)) div SizeOf(Char));
end;


...但这感觉很丑,“特例”。我想知道是否有更干净的方法来编写此代码,以便以后任何人(我!)查看代码时都不会立即问“为什么将尾随的char从流中删除?”。

编辑:避免问题的一种方法是添加评论。但是,除此之外呢?

最佳答案

如果以CF_UNICODETEXT为目标,则需要专门指定unicode字符串:

// For old Delphi versions
{$IFNDEF UNICODE}
type
  UnicodeString = WideString;
{$ENDIF}

// For CF_TEXT
function MemoryStreamToAnsiString(M: TMemoryStream): AnsiString;
begin
  SetString(Result, M.Memory, M.Size);
  if (Result <> '') and (Result[Length(Result)] = #0) then
    SetLength(Result, Length(Result) - 1);
end;

// For CF_UNICODETEXT
function MemoryStreamToUnicodeString(M: TMemoryStream): UnicodeString;
begin
  SetString(Result, M.Memory, M.Size div SizeOf(WideChar));
  if (Result <> '') and (Result[Length(Result)] = #0) then
    SetLength(Result, Length(Result) - 1);
end;

// I'm not sure that you should use this form
function MemoryStreamToString(M: TMemoryStream): String;
begin
  SetString(Result, M.Memory, M.Size div SizeOf(Char));
  if (Result <> '') and (Result[Length(Result)] = #0) then
    SetLength(Result, Length(Result) - 1);
end;


如果您100%确保该字符串以零结尾,则:

// For CF_TEXT
function MemoryStreamToAnsiString(M: TMemoryStream): AnsiString;
begin
  SetString(Result, M.Memory, M.Size - 1);
end;

// For CF_UNICODETEXT
function MemoryStreamToUnicodeString(M: TMemoryStream): UnicodeString;
begin
  SetString(Result, M.Memory, (M.Size div SizeOf(WideChar)) - 1);
end;

function MemoryStreamToString(M: TMemoryStream): String;
begin
  SetString(Result, M.Memory, (M.Size div SizeOf(Char)) - 1);
end;

关于delphi - 将以null结尾的内存流转换为unicode字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4738680/

相关文章:

delphi - 如何使固定长度的 Delphi 字符串使用宽字符?

c - 如何让日文字符显示

delphi - 更改 Delphi 中 Firemonkey 应用程序中大多数控件(即 TPanel)的颜色(仅限 XE2 Update4 和 XE3)

delphi - 从序列化数据创建数字人物指纹模板

delphi - 将 Paradox 转换为 MDB

delphi - 消息处理程序中的 DefaultHandler(Message) 和 "inherited"有什么区别?

c# - 谁拥有放置在剪贴板上的 MemoryStream 对象? (或者应该使用 MemoryStream 以外的东西吗?)

c# - MemoryStream 和深度克隆

c# - 如何在 C# 中快速读取二进制文件? (ReadOnlySpan 与 MemoryStream)

Javascript Unicode 转义反斜杠