如何将空终止字符串转换为字符串?
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
参数。
我想将一些数据记录存储到磁盘。我想让每个数据记录的大小相等,这样我就可以快速计算并跳转到某个记录。 因此,我将记录中唯一的字符串存储为字符数组:
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
参数。