简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM