繁体   English   中英

我如何在 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);

但是 compailer 说警告在第 43 和 44 行:这些是什么:

nomFumadors : lexicon := ("Macia","Xisco","Toni","Laura","Rocky","Paz");
nomNoFumadors : lexicon := ("Marina","Marta","Joan","Africa","America");

有人可以帮我吗?

您声明了您的数组以保存长度为 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))

另一种解决方案是使用字符串,截断长字符串并填充短字符串:

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"), ...

另一个选项是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;

其他人提到了有界和无界字符串。 您也可以使用 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;

类似于杰夫卡特的回答,但使用 function 将任何字符串强制转换为固定字符串......

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),则 function 中的结果声明变为

Result : Lexicon_Data
   with Relaxed_Initialization;

.. 并且 function To_Lexicon_Data 被证明是无运行时错误的。

请注意 Lexicon 的额外项 Mark,因为您需要七项才能使 Lexicon 声明有效。

以 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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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