Ada常量字符串文字数组

时间:2016-12-14 20:21:14

标签: arrays string ada

我在C中有一个大型数组,我想进入我的ada项目。该数组用于存储稍后将加载的资产的文件名。它看起来像:

const char *filenames[NUMBER_OF_FILES] = {
    /* file[0] */ "res/0.file",
    /* ... */
    /* file[n] */ "res/some_more/complicated/file.name"
};

我想把它移到ada包体中,但找不到合适的方法。显然我的第一次尝试是:

filenames : constant array (File_Index) of String := (
    index_0 => "res/0.file",
    --  ...
    index_n => "res/some_more/complicated/file.name"
);

但当然String是一种不受约束的类型,因此Ada不允许这样做。我将它切换为使用Unbounded_Strings,但它非常难看(必须用To_Unbounded_String包装每个字符串。

有没有办法制作一个无约束类型的数组,其大小将在编译时像这样知道,或者我是否必须使用无界字符串?

3 个答案:

答案 0 :(得分:3)

数组不能包含不定类型的对象。

基本上你有两个选择:

  1. 使用除阵列之外的其他容器。
  2. 以确定的类型封装字符串。
  3. 所以你可以使用Ada.Containers.Indefinite_Vectors而不是数组:

    with Ada.Containers.Indefinite_Vectors;
    
    package Settings is
       ------------------------------------------------------------------
       --  You may want to put this block in a separate package:
       package String_Vectors is
         new Ada.Containers.Indefinite_Vectors (Index_Type   => Positive,
                                                Element_Type => String);
       function "+" (Left, Right : String) return String_Vectors.Vector
         renames String_Vectors."&";
       function "+" (Left  : String_Vectors.Vector;
                     Right : String) return String_Vectors.Vector
         renames String_Vectors."&";
       ------------------------------------------------------------------
    
       File_Names : constant String_Vectors.Vector :=
                      "/some/file/name" +
                      "/var/spool/mail/mine" +
                      "/etc/passwd";
    end Settings;
    

    因此,您可以使用Ada.Strings.Unbounded.Unbounded_String代替String

    with Ada.Strings.Unbounded;
    
    package Settings_V2 is
       function "+" (Item : in String) return Ada.Strings.Unbounded.Unbounded_String
         renames Ada.Strings.Unbounded.To_Unbounded_String;
       type String_Array is array (Positive range <>)
         of Ada.Strings.Unbounded.Unbounded_String;
    
       File_Names : constant String_Array :=
                      (+"/some/file/name",
                       +"/var/spool/mail/mine",
                       +"/etc/passwd");
    end Settings_V2;
    

答案 1 :(得分:2)

它有点低级和重复,但也许你可以创建一个小程序(甚至可能在Ada中!)来生成像

这样的东西
with Ada.Text_IO; use Ada.Text_IO;
procedure Lambdabeta is
   F1 : aliased constant String := "res/0.file";
   F2 : aliased constant String := "res/some_more/complicated/file.name";
   type Strings is array (Positive range <>) of access constant String;
   Filenames : constant Strings := (F1'Access,
                                    F2'Access);
begin
   for J in Filenames'Range loop
      Put_Line (Filenames (J).all);
   end loop;
end Lambdabeta;

另请参阅this answer,尽量减少使用To_Unbounded_String的痛苦。

答案 2 :(得分:0)

尚未提及的是你可以使用一个函数:

subtype File_Index is Integer range 1 .. 3;
function Filename (Index : File_Index) return String is
begin
   case Index is
   when 1 => return "res/0.file";
   when 2 => return "res/1.file";
   when 3 => return "res/some_more/complicated/file.name";
   end case;
end Filename;

在代码中使用Filename (1)与访问数组元素相同。