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

时间:2015-08-22 22:45:07

标签: delphi delphi-xe7

我想将一些数据记录存储到磁盘。我希望每个数据记录具有相同的大小,以便我可以快速计算并跳转到某个记录。 所以,我将记录中唯一的字符串存储为字符数组:

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等

我想截断#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;

有更好的方法吗?

2 个答案:

答案 0 :(得分:5)

您可以将以空格分组的PChar直接分配给String

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

确保TDiskName始终包含空终止符。如果它可以完全填满没有null的字符,你将不得不这样做:

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;

答案 1 :(得分:3)

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

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

  

基于零的字符数组与PChar和PWideChar兼容。当您使用字符数组代替指针值时,编译器会将数组转换为指针常量,其值对应于数组的第一个元素的地址。

这使您更容易与期望PChar参数的函数互操作。

顺便说一句,按值传递TFileNameIO是低效的,因为它涉及内存副本。通过引用传递这些类型。例如,作为const参数。