简体   繁体   English

我如何在 Ada 中定义一个字符串数组?

[英]How can I define an Array of Strings in Ada?

What I want is to define an array of Strings in Ada.我想要的是在 Ada 中定义一个字符串数组。

I'm trying to execute this code:我正在尝试执行此代码:

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");

And the compiler says:编译器说:

warning:wrong length for array of subtype of "String" defined at line 42

My line 42 is this:我的第 42 行是这样的:

type lexicon is array(1..7) of String(1..20);

But compailer says the warning is in line 43 and 44: what are these:但是 compailer 说警告在第 43 和 44 行:这些是什么:

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

Can somebody help me with that?有人可以帮我吗?

You declared your array to hold Strings of length 20. The String literals you give are less than 20 Characters long.您声明了您的数组以保存长度为 20 的字符串。您提供的字符串文字长度小于 20 个字符。 Hence the error.因此错误。

You seem to be looking for a string type that contains a maximum of 20 characters.您似乎正在寻找最多包含 20 个字符的字符串类型。 This is provided in Ada.Strings.Bounded :这在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"));

To get back a String from a Bounded_String, use eg To_String (Lexicon (2)) .要从 Bounded_String 取回字符串,请使用To_String (Lexicon (2))

Another solution is to use String, truncate long strings, and pad short strings:另一种解决方案是使用字符串,截断长字符串并填充短字符串:

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

Another option is Unbounded_String (as its name suggests, length is variable and unlimited):另一个选项是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;

Others have mentioned bounded and unbounded strings.其他人提到了有界和无界字符串。 You can also use Indefinite_Vectors.您也可以使用 Indefinite_Vectors。 You can use the "&" operator to initialize them (as opposed to the initializer list though the next version of Ada is adding initializer lists to containers).您可以使用“&”运算符来初始化它们(与初始化列表相反,尽管下一版本的 Ada 正在将初始化列表添加到容器中)。 You can use a vector just like an array by passing indexes in plus you get a lot of other additional functionality.您可以通过传入索引来使用向量,就像数组一样,您还可以获得许多其他附加功能。

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;

Similar to Jeff Carter's answer, but using a function to coerce any string into a fixed string...类似于杰夫卡特的回答,但使用 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;

If you wanted to prove AoRTE (ie SparkAda) then the declaration for Result in the function becomes如果您想证明 AoRTE(即 SparkAda),则 function 中的结果声明变为

Result : Lexicon_Data
   with Relaxed_Initialization;

.. and the function To_Lexicon_Data is proved as being runtime error free. .. 并且 function To_Lexicon_Data 被证明是无运行时错误的。

Note the extra item for Lexicon, Mark, since you need seven items for the Lexicon declaration to be valid.请注意 Lexicon 的额外项 Mark,因为您需要七项才能使 Lexicon 声明有效。

Building upon the solution by Mark, but simplifying thanks to the operations from Ada.Strings.Fixed .以 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