[英]How to convert a null terminated string to string?
I want to store to disk some data records.我想将一些数据记录存储到磁盘。 I want to have each data record of equal size so I can quickly compute and jump to a certain record.
我希望每个数据记录的大小相等,这样我就可以快速计算并跳转到某个记录。 So, I store the only string in my record as an array of chars:
因此,我将记录中唯一的字符串存储为字符数组:
type TFileNameIO = array[1..512] of Char;
After I read the string from disk, the content of my string is like this:从磁盘读取字符串后,我的字符串内容是这样的:
c:\\windows#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 etc
c:\\windows#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 等
I want to truncate the #0 characters, and I do something like this:我想截断 #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;
There is a better way to do it?有更好的方法吗?
You can assign a null-terminated PChar
directly to a String
:您可以将空终止的
PChar
直接分配给String
:
function GetFileName(DiskName: TFileNameIO): string;
begin
Result := PChar(@DiskName);
end;
Just make sure the TDiskName
always contains a null terminator.只需确保
TDiskName
始终包含空终止符。 If it can ever be completely full of characters without a null, you will have to do this instead:如果它可以完全充满没有 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;
Your function is not necessary because you can simply assign a character array to a string variable.您的函数不是必需的,因为您可以简单地将字符数组分配给字符串变量。
type
TCharArray = array [1..512] of Char;
....
var
arr: TCharArray;
str: string;
....
arr := ...;
str := arr;
This results in str
being assigned the contents of arr
.这导致
str
被分配了arr
的内容。 The compiler implements this with a call to System._UStrFromWArray
which first of all looks for a null-terminator.编译器通过调用
System._UStrFromWArray
来实现这一点,它首先查找空终止符。 If it finds one, that determines the length of str
.如果找到一个,则确定
str
的长度。 Otherwise, the entire contents of the array are copied, and Length(str)=Length(arr)
.否则,将复制数组的全部内容,并且
Length(str)=Length(arr)
。
As a broader point, I would recommend that you change to using zero-based character arrays.作为更广泛的观点,我建议您改为使用从零开始的字符数组。 From the documentation :
从文档:
Zero-based character arrays are compatible with PChar and PWideChar.
从零开始的字符数组与 PChar 和 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.
当您使用字符数组代替指针值时,编译器会将数组转换为指针常量,其值对应于数组第一个元素的地址。
This makes it easier for you to interop with functions that expect PChar
arguments.这使您可以更轻松地与需要
PChar
参数的函数进行互操作。
As an aside, passing TFileNameIO
by value is inefficient because it involves a memory copy.顺便说
TFileNameIO
按值传递TFileNameIO
效率低下,因为它涉及内存复制。 Pass such types by reference.通过引用传递此类类型。 For instance as a
const
parameter.例如作为
const
参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.