如何将空终止字符串转换为字符串?

How to convert a null terminated string to string?

我想将一些数据记录存储到磁盘。我想让每个数据记录的大小相等,这样我就可以快速计算并跳转到某个记录。 因此,我将记录中唯一的字符串存储为字符数组:

type TFileNameIO = array[1..512] of Char;

我从磁盘读取字符串后,我的字符串内容是这样的:

c:\windows#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 etc

我想截断 #0 个字符,我这样做了:

function GetFileName(DiskName: TFileNameIO): string;
VAR PC: PChar;
begin
 SetString(Result, PChar(@DiskName), Length(DiskName));     <----- here Result is: c:\windows#0#0#0 etc
 PC:= PChar(Result);
 Result:= WideCharToString(PC);
end;

有更好的方法吗?

您可以将空终止的 PChar 直接分配给 String:

function GetFileName(DiskName: TFileNameIO): string;
begin
 Result := PChar(@DiskName);
end;

只需确保 TDiskName 始终包含空终止符。如果它可以完全充满字符而没有空值,则您将不得不这样做:

function GetFileName(DiskName: TFileNameIO): string;
var
 Len, I: Integer;
begin
  Len := 0;
  For I := Low(DiskName) to High(DiskName) do
  begin
    if DiskName[I] = #0 then Break;
    Inc(Len);
  end;
  SetString(Result, PChar(@DiskName), Len);
end;

您的函数不是必需的,因为您可以简单地将字符数组分配给字符串变量。

type
  TCharArray = array [1..512] of Char;
....
var
  arr: TCharArray;
  str: string;
....
arr := ...;
str := arr;

这导致 str 被分配 arr 的内容。编译器通过调用 System._UStrFromWArray 来实现这一点,它首先查找空终止符。如果找到一个,则确定 str 的长度。否则,复制数组的全部内容,并且 Length(str)=Length(arr).

更广泛地说,我建议您改为使用从零开始的字符数组。来自 documentation:

Zero-based character arrays are compatible with PChar and PWideChar. When you use a character array in place of a pointer value, the compiler converts the array to a pointer constant whose value corresponds to the address of the first element of the array.

这使您可以更轻松地与需要 PChar 个参数的函数进行互操作。

顺便说一句,按值传递 TFileNameIO 效率低下,因为它涉及内存复制。通过引用传递此类类型。例如作为 const 参数。