变体记录中的短字符串?
我希望能够访问短字符串的部分作为记录的一部分
这
TMyRecord = record
case Boolean of
True:
(
EntireString: String[20];
);
False
(
StringStart: String[8];
StringMiddle: String[4];
StringEnd: String[8];
);
end;
可能吗?或者我必须单独声明每个字符
TMyRecord = record
private
Chars: Array[1..20] of Char;
Function GetStringStart:String;
Procedure SetStringStart(Value: String);
public
Property StringStart: String read GetStringStart write SetStringStart; // Can I have properties on a record?
end;
Function GetStringStart: String;
begin
Result := Chars[1] + Char[2]....;
end;
Procedure SetStringStart(Value: String);
begin
for i := 1 to 8 do
begin
Chars[i] := Value[i];
end;
end;
这可能/值得吗?
I'd like to be able to access sections of a short string as part of a record
Something like
TMyRecord = record
case Boolean of
True:
(
EntireString: String[20];
);
False
(
StringStart: String[8];
StringMiddle: String[4];
StringEnd: String[8];
);
end;
Is this possible or would I have to declare each char individually
TMyRecord = record
private
Chars: Array[1..20] of Char;
Function GetStringStart:String;
Procedure SetStringStart(Value: String);
public
Property StringStart: String read GetStringStart write SetStringStart; // Can I have properties on a record?
end;
Function GetStringStart: String;
begin
Result := Chars[1] + Char[2]....;
end;
Procedure SetStringStart(Value: String);
begin
for i := 1 to 8 do
begin
Chars[i] := Value[i];
end;
end;
Is this possible / worth the effort?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Delphi 短字符串不仅仅包含字符串内容。数据结构中的初始字节包含字符串的长度。这就是短字符串限制为 255 个字符的原因。
因此,您不能按照您建议的方式在变体数组中使用短字符串。
您可以做的是调整基于 getter 和 setter 方法的第二种方法,使其更具可读性。
例如:
您可能会考虑使用字符串而不是字符数组,但是在不确切知道您的根本问题是什么的情况下,很难 100% 确定该建议。
最后一个想法是,为什么不扭转这个问题呢?存储 3 个字符串:
StartString
、MiddleString
和EndString
。然后有一个由名为EntireString
的 getter 和 setter 支持的属性。当您读取EntireString
时,它将由 3 个单独的部分拼凑在一起,而当您写入它时,它会将各个部分拉出。我怀疑这样会更容易。A Delphi short string contains more than just the string contents. The initial byte in the data structure contains the length of the string. This is why short strings are limited to 255 characters.
So, you can't use short strings in your variant array the way you propose.
What you could do is adapt your second approach based on getter and setter methods to be a bit more readable.
For example:
You might consider using a string rather than a char array, but it's a little hard to be 100% sure of that advice without knowing exactly what your underlying problem is.
As a final thought, why not turn the problem around? Store 3 strings:
StartString
,MiddleString
andEndString
. Then have a property backed with a getter and setter calledEntireString
. When you readEntireString
it pieces it together from the 3 individual parts, and when you write to it it pulls the individual parts out. I suspect it would be easier that way around.您的第一个示例不考虑长度字节。内存布局如下所示:
(L = 长度字节)。
根据您的要求(例如:部分字符串总是 8、4 和 8 个字符吗?)我会尝试使用 System 存储部分字符串并使
EntireString
属性.Copy、StrUtils.LeftStr 等Your first sample doesn't consider the length byte. The memory layout looks like this:
(L = length byte).
Depending on your requirements (e.g.: Are the partial strings always 8, 4 and 8 Chars?) I'd try storing the partial strings and make
EntireString
the property, using System.Copy, StrUtils.LeftStr etc.ShortString
具有隐含长度,因此您的第一个示例将把子字符串的长度部分映射到主字符串的顶部。您的第二个示例是开始的方式,请注意以下事项:
编辑
这完全取决于您想要这样做的原因,混合字符数组和字符串会给您带来麻烦,因为字符串可能比数组长度短。
小例子:
这个类或多或少做了你想要的事情:
ShortString
has an implied length, so your first example will map the length parts of the substrings on top of the main string.Your second sample is the way to start, with these notes:
Edit
It totally depend on the reason you want this, and mixing character arrays and strings will get you into trouble because strings can be shorter than the array length.
Small example:
This class does more or less what you want:
正如其他人所说,它不起作用,因为变体大小的记录会在
EntireString
类型的中间添加一些StringStart/StringMiddle/StringEnd
的长度。您将 C 的 *char 类型与 pascal Shortstring 类型混淆了。在位置
[0]
处有一个隐藏字符,它是shortstring
长度。您可以使用常规字符串类型,然后有意拆分:
请注意,
out
参数类型将在调用函数之前将所有输出 String* 变量设置为 ''。此版本预计输入 20 个字符长的整个字符串。
如果您想避免来自/到
string[255]
的隐藏副本(当您使用shortstring
时会发生这种情况),您可以使用短字符串,但使用精确长度的自定义类型输入并使用string[n]
(n<255):As other stated, it won't work, because the variant-sized record will add some lengths for
StringStart/StringMiddle/StringEnd
in the middle of theEntireString
type.You are confusing the
*char
type of C with the pascalshortstring
type. There is an hidden character at position[0]
which is theshortstring
length.You could use regular string type, then split in on purpose:
Note that the
out
parameter type will set all output String* variables into '' before calling the function.This version will expect entering entire string of 20 chars long.
You could use shortstrings, but with custom types of the exact length, if you want to avoid hidden copies from/to
string[255]
(which occur when you use ashortstring
type and work withstring[n]
with n<255):