我想将一些数据记录存储到磁盘。我希望每个数据记录具有相同的大小,以便我可以快速计算并跳转到某个记录。 所以,我将记录中唯一的字符串存储为字符数组:
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;
有更好的方法吗?
答案 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
参数。