包含可变长度字符串的记录数组
An array of records containing variable-length strings
我想要一个包含整数和可变长度字符串的记录,如下所示:
type Entry is
record
Value: Integer;
Label: String;
end record;
我 运行 the issue 认为你不能将不受约束的字符串放入记录类型中,所以按照当时的建议 link 我尝试了
type Entry(Label_Length : Natural) is
record
Value: Integer;
Label: String(1..Label_Length);
end record;
但现在的问题是,我想要这些东西的数组:
Entries : Array(1..2) of Entry := (
(Label_Length => 0, Value => 1, Label => ""),
(Label_Length => 0, Value => 2, Label => "")
);
有人告诉我
main.adb:17:28: unconstrained element type in array declaration
我只想声明一个包含这些东西的(常量)数组,并以直观的方式输入标签和值(我已经对必须计算字符串长度并输入 Label_Length 手动)。我该怎么做?
[entry
是保留字。]
如果您想要一个数组,所有条目的大小必须相同。第二条记录的大小是 Label_Length
(4) + Value
(4) + Label
(Character
(1) * Label_Length
) 即介于 8刚好超过 2**31 个字节。
诀窍是固定最大大小并给出默认值:
subtype Ent_Label_Length is Natural range 0 .. 32;
type Ent (Label_Length : Ent_Label_Length := Ent_Label_Length'Last) is
record
Value : Integer;
Label : String (1 .. Label_Length);
end record;
您可以使用 Ada.Strings.Bounded
(ARM A.4.4).
来省去编写此代码(以及计算每个字符串的长度)的麻烦
如果您不知道标签字段的最大大小,您可以使用 Ada.Strings.Unbounded。
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO.Unbounded_IO; use Ada.Text_IO.Unbounded_IO;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Main is
type Ent is record
Value : Integer;
Label : Unbounded_String;
end record;
type ent_array is array (1 .. 4) of Ent;
Foo : ent_array;
begin
for I of Foo loop
Put ("Enter a value: ");
Get (I.Value);
Skip_Line;
Put ("Enter a label: ");
I.Label := Get_Line;
New_Line;
end loop;
Put_Line ("Array Foo contents:");
for I of Foo loop
Put (I.Value'Image & " ");
Put_Line (I.Label);
end loop;
end Main;
如果您不介意略有不同的语法,您也可以考虑使用 Ada.Containers.Indefinite_Vectors 包代替数组。然后每个元素可以是不同的大小。向量可以像数组一样用于 for 循环:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Indefinite_Vectors; use Ada.Containers;
procedure Main is
type Entry_Info(Label_Length : Natural) is
record
Value: Integer;
Label: String(1..Label_Length);
end record;
package Vectors is new Indefinite_Vectors
(Index_Type => Positive,
Element_Type => Entry_Info);
use type Vectors.Vector; -- so you can use the & operator
Entries : Vectors.Vector := Vectors.Empty_Vector
& (Label_Length => 0, Value => 1, Label => "")
& (Label_Length => 1, Value => 2, Label => "A");
begin
for Info of Entries loop
Put_Line(Info.Value'Image & " => " & Info.Label);
end loop;
end Main;
还有一个但可能更粗糙的方法是将字符串放在堆上并使用访问值:
type String_Ref is access String;
type Entry_T is record
Value: Integer;
Label: String_Ref;
end record;
要分配字符串,请使用带有初始值的“new”:
Entries : constant array(1..2) of Entry_T := (
(Value => 1, Label => new String'("First entry")),
(Value => 2, Label => new String'("Second entry"))
);
要获取 Label 的值,请遵循“.all”:
for E of Entries loop
Ada.Text_IO.Put_Line (
"Value" & E.Value'Image
& ", label " & E.Label.all);
end loop;
如果我们发布奇怪的解决方案,您也可以使用支架:
package String_Holders is new Ada.Containers.Indefinite_Holders
(Element_Type => String);
type Entry_Is_Reserved is record
Value : Integer;
Label : String_Holders.Holder;
end record;
我想要一个包含整数和可变长度字符串的记录,如下所示:
type Entry is
record
Value: Integer;
Label: String;
end record;
我 运行 the issue 认为你不能将不受约束的字符串放入记录类型中,所以按照当时的建议 link 我尝试了
type Entry(Label_Length : Natural) is
record
Value: Integer;
Label: String(1..Label_Length);
end record;
但现在的问题是,我想要这些东西的数组:
Entries : Array(1..2) of Entry := (
(Label_Length => 0, Value => 1, Label => ""),
(Label_Length => 0, Value => 2, Label => "")
);
有人告诉我
main.adb:17:28: unconstrained element type in array declaration
我只想声明一个包含这些东西的(常量)数组,并以直观的方式输入标签和值(我已经对必须计算字符串长度并输入 Label_Length 手动)。我该怎么做?
[entry
是保留字。]
如果您想要一个数组,所有条目的大小必须相同。第二条记录的大小是 Label_Length
(4) + Value
(4) + Label
(Character
(1) * Label_Length
) 即介于 8刚好超过 2**31 个字节。
诀窍是固定最大大小并给出默认值:
subtype Ent_Label_Length is Natural range 0 .. 32;
type Ent (Label_Length : Ent_Label_Length := Ent_Label_Length'Last) is
record
Value : Integer;
Label : String (1 .. Label_Length);
end record;
您可以使用 Ada.Strings.Bounded
(ARM A.4.4).
如果您不知道标签字段的最大大小,您可以使用 Ada.Strings.Unbounded。
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO.Unbounded_IO; use Ada.Text_IO.Unbounded_IO;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Main is
type Ent is record
Value : Integer;
Label : Unbounded_String;
end record;
type ent_array is array (1 .. 4) of Ent;
Foo : ent_array;
begin
for I of Foo loop
Put ("Enter a value: ");
Get (I.Value);
Skip_Line;
Put ("Enter a label: ");
I.Label := Get_Line;
New_Line;
end loop;
Put_Line ("Array Foo contents:");
for I of Foo loop
Put (I.Value'Image & " ");
Put_Line (I.Label);
end loop;
end Main;
如果您不介意略有不同的语法,您也可以考虑使用 Ada.Containers.Indefinite_Vectors 包代替数组。然后每个元素可以是不同的大小。向量可以像数组一样用于 for 循环:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Indefinite_Vectors; use Ada.Containers;
procedure Main is
type Entry_Info(Label_Length : Natural) is
record
Value: Integer;
Label: String(1..Label_Length);
end record;
package Vectors is new Indefinite_Vectors
(Index_Type => Positive,
Element_Type => Entry_Info);
use type Vectors.Vector; -- so you can use the & operator
Entries : Vectors.Vector := Vectors.Empty_Vector
& (Label_Length => 0, Value => 1, Label => "")
& (Label_Length => 1, Value => 2, Label => "A");
begin
for Info of Entries loop
Put_Line(Info.Value'Image & " => " & Info.Label);
end loop;
end Main;
还有一个但可能更粗糙的方法是将字符串放在堆上并使用访问值:
type String_Ref is access String;
type Entry_T is record
Value: Integer;
Label: String_Ref;
end record;
要分配字符串,请使用带有初始值的“new”:
Entries : constant array(1..2) of Entry_T := (
(Value => 1, Label => new String'("First entry")),
(Value => 2, Label => new String'("Second entry"))
);
要获取 Label 的值,请遵循“.all”:
for E of Entries loop
Ada.Text_IO.Put_Line (
"Value" & E.Value'Image
& ", label " & E.Label.all);
end loop;
如果我们发布奇怪的解决方案,您也可以使用支架:
package String_Holders is new Ada.Containers.Indefinite_Holders
(Element_Type => String);
type Entry_Is_Reserved is record
Value : Integer;
Label : String_Holders.Holder;
end record;