提问人:Macia Salva 提问时间:2/3/2022 最后编辑:trashgodMacia Salva 更新时间:7/24/2022 访问量:542
如何在 Ada 中定义字符串数组?
How can I define an Array of Strings in Ada?
问:
我想要的是在 Ada 中定义一个字符串数组。
我正在尝试执行以下代码:
type String is array (Positive range <>) of Character;
type lexicon is array(1..7) of String(1..20);
nomFumadors : lexicon := ("Macia","Xisco","Toni","Laura","Rocky","Paz");
nomNoFumadors : lexicon := ("Marina","Marta","Joan","Africa","America");
编译器说:
warning:wrong length for array of subtype of "String" defined at line 42
我的第 42 行是这样的:
type lexicon is array(1..7) of String(1..20);
但公司表示,警告在第 43 行和第 44 行:这些是什么:
nomFumadors : lexicon := ("Macia","Xisco","Toni","Laura","Rocky","Paz");
nomNoFumadors : lexicon := ("Marina","Marta","Joan","Africa","America");
有人可以帮我吗?
答:
5赞
flyx
2/3/2022
#1
您声明了数组以保存长度为 20 的字符串。您提供的字符串文本长度少于 20 个字符。因此出现错误。
您似乎正在寻找最多包含 20 个字符的字符串类型。这在以下语言中提供:Ada.Strings.Bounded
package Max_20_String is new Ada.Strings.Bounded.Generic_Bounded_Length (20);
use Max_20_String;
type Lexicon is array (1..7) of Bounded_String; -- from Max_20_String
nomFumadors : Lexicon := (To_Bounded_String ("Macia"),
To_Bounded_String ("Xisco"),
To_Bounded_String ("Toni"),
To_Bounded_String ("Laura"),
To_Bounded_String ("Rocky"),
To_Bounded_String ("Paz"));
要从Bounded_String中取回字符串,请使用 例如.To_String (Lexicon (2))
5赞
Zerte
2/3/2022
#2
另一种选择是(顾名思义,长度是可变的和无限的):Unbounded_String
with Ada.Strings.Unbounded;
procedure Fumador is
use Ada.Strings.Unbounded;
subtype VString is Unbounded_String;
function "+" (Source : in String) return VString renames To_Unbounded_String;
type Lexicon is array (Integer range <>) of VString; -- Unknown number of people.
nomFumadors : Lexicon := (+"Macia", +"Xisco", +"Toni", +"Laura", +"Rocky", +"Paz");
nomNoFumadors : Lexicon := (+"Marina", +"Marta", +"Joan", +"Africa", +"America");
begin
null;
end;
评论
1赞
2/3/2022
当然,函数重命名将在两个答案中都有效。
6赞
Jere
2/4/2022
#3
其他人则提到了有界和无界字符串。您也可以使用Indefinite_Vectors。您可以使用“&”运算符来初始化它们(与初始值设定项列表相反,尽管 Ada 的下一个版本正在将初始值设定项列表添加到容器中)。你可以像数组一样使用向量,通过传入索引,此外,你还能获得许多其他附加功能。
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Indefinite_Vectors;
procedure Hello is
package Vectors is new Ada.Containers.Indefinite_Vectors
(Index_Type => Positive,
Element_Type => String);
use type Vectors.Vector;
nomFumadors : Vectors.Vector
:= Vectors.Empty_Vector
& "Macia"
& "Xisco"
& "Toni"
& "Laura"
& "Rocky"
& "Paz";
nomNoFumadors : Vectors.Vector
:= Vectors.Empty_Vector
& "Marina"
& "Marta"
& "Joan"
& "Africa"
& "America";
begin
Put_Line("Hello, world!");
-- Loop through Elements
for Name of nomFumadors loop
Put_Line(Name);
end loop;
-- Loop by index
for Index in nomNoFumadors.Iterate loop
Put_Line(nomNoFumadors(Index));
end loop;
end Hello;
1赞
Jeffrey R. Carter
2/4/2022
#4
另一种解决方案是使用 String,截断长字符串并填充短字符串:
Max : constant := 20;
subtype S20 is String (1 .. Max);
type Lexicon is array (1 .. 7) of S20;
function To20 (S : in String) return S20 is
(if S'Length >= Max then S (S'First .. S'First + Max - 1)
else S & (S'Length + 1 .. Max => ' ') );
V : Lexicon := (To20 (""), To20 ("Hello"), To20 ("1234567890123456789012345"), ...
0赞
Mark
2/9/2022
#5
类似于 Jeff Carter 的回答,但使用函数将任何字符串强制转换为固定字符串......
procedure Main is
subtype Lexicon_Data is String (1 .. 20);
type Lexicon is array (1 .. 7) of Lexicon_Data;
function To_Lexicon_Data
(Value : in String)
return Lexicon_Data
is
Result : Lexicon_Data;
begin
if Value'Length < 1 then
-- Empty string returns a bunch of spaces
Result := (others => ' ');
else
declare
Offset : constant Natural :=
Value'First - Lexicon_Data'First;
begin
if Value'Length > Lexicon_Data'Length then
-- Length exceeds range, so truncate
Result (Lexicon_Data'Range) := Lexicon_Data
(Value (Offset + 1 .. Offset + Lexicon_Data'Length));
else
-- Copy into result, and pad right with spaces
Result := (others => ' ');
Result (Lexicon_Data'First .. Value'Length) :=
(Value (Offset + 1 .. Offset + Value'Length));
end if;
end;
end if;
return Result;
end To_Lexicon_Data;
nomFumadors : constant Lexicon :=
(To_Lexicon_Data ("Macia"),
To_Lexicon_Data ("Xisco"),
To_Lexicon_Data ("Toni"),
To_Lexicon_Data ("Laura"),
To_Lexicon_Data ("Rocky"),
To_Lexicon_Data ("Paz"),
To_Lexicon_Data ("Mark"));
begin
-- Insert code here.
null;
end Main;
如果要证明 AoRTE(即 SparkAda),则函数中 Result 的声明变为
Result : Lexicon_Data
with Relaxed_Initialization;
..并且该函数To_Lexicon_Data被证明是运行时没有错误的。
请注意 Lexicon 的额外项目 Mark,因为 Lexicon 声明需要 7 个项目才能有效。
评论
0赞
Gneuromante
3/3/2022
这可以使用 Ada.Strings.Fixed.Move 进行简化:en.wikibooks.org/wiki/Ada_Programming/Libraries/...
0赞
Gneuromante
3/3/2022
或者更好的是,使用 Ada.Strings.Fixed.Head。我想我将提供它作为另一个替代答案。
0赞
Gneuromante
3/3/2022
#6
以 Mark 的解决方案为基础,但由于 Ada.Strings.Fixed
的操作而简化。
with Ada.Strings.Fixed;
with Ada.Text_IO;
procedure Main is
subtype Lexicon_Data is String (1 .. 20);
type Lexicon is array (1 .. 7) of Lexicon_Data;
function To_Lexicon_Data
(Value : in String)
return Lexicon_Data
is
begin
return Ada.Strings.Fixed.Head (Value, Lexicon_Data'Length);
end To_Lexicon_Data;
nomFumadors : constant Lexicon :=
(To_Lexicon_Data ("Macia"),
To_Lexicon_Data ("Xisco"),
To_Lexicon_Data ("Toni"),
To_Lexicon_Data ("Laura"),
To_Lexicon_Data ("Rocky"),
To_Lexicon_Data ("Paz"),
To_Lexicon_Data ("Mark"));
begin
for Item of nomFumadors loop
Ada.Text_IO.Put_Line (Ada.Strings.Fixed.Trim (Item, Ada.Strings.Both));
end loop;
end Main;
评论