【问题标题】:String handling in AdaAda 中的字符串处理
【发布时间】:2014-04-04 06:04:44
【问题描述】:

我试图在 Ada 中定义一个字符串数组来存储可变大小的字符串。 我遇到的问题是我必须预先定义我在编译时不知道的字符串的大小,并且 Unbounded_Strings String_Split.Create 不起作用,因为它需要 Standard.String。

下面是我的代码,我需要能够解析可变大小的字符串,而不是 只是固定长度 4.

提前致谢。

type StrArray is array(1..7) of String(1..4);

function Split(Line : String;Sep : String) return StrArray is
    Tokens : String_Split.Slice_Set;
    Output : StrArray;
    Count : Natural := 0;
begin
    String_Split.Create(s => Tokens,
                        From => Line,
                        Separators => Sep,
                        Mode => String_Split.Single);

    For I in 1 .. String_Split.Slice_Count (Tokens) loop
         Count := Count + 1;
         Output(Count) := String_Split.Slice(Tokens,I);  -- Not sure how to convert                Slice_Count to Integer either!
    end loop;

    return Output;

end Split;

【问题讨论】:

    标签: string ada


    【解决方案1】:

    GNAT.String_Split 使用 String 的事实并不意味着您的 StrArray 必须这样做。而且您需要满足具有不同数量标记的输入字符串,因此首先将 StrArray 声明为不受约束的数组类型:

    type StrArray is array (Positive range <>)
      of Ada.Strings.Unbounded.Unbounded_String;
    

    现在Split 是这样开始的:

    function Split (Line : String; Sep : String) return StrArray is
       Tokens : GNAT.String_Split.Slice_Set;
    begin
    

    (我们还不能声明Output,我们也不需要Count;我不得不去谷歌发现String_Split是一个GNAT实用程序包)。

    首先要做的是拆分输入行,这样我们就知道Output需要多大(顺便问一下,你真的要Single吗?):

       GNAT.String_Split.Create (S => Tokens,
                                 From => Line,
                                 Separators => Sep,
                                 Mode => GNAT.String_Split.Single);
    

    现在我们可以使用Slice_Count 声明Output。注意转换为Natural(不是Positive;如果输入为空字符串,则没有标记,因此输出将为空数组,范围为1 .. 0)。

       declare
          Output : StrArray
            (1 .. Natural (GNAT.String_Split.Slice_Count (Tokens)));
       begin
    

    现在用令牌填充Output。 AdaCore 选择将Slice_Number 实现为new Natural,而不是作为Natural 的子类型,这就是我们需要转换的原因。

          for I in Output'Range loop
             Output (I) :=
               Ada.Strings.Unbounded.To_Unbounded_String
                 (GNAT.String_Split.Slice
                    (Tokens, GNAT.String_Split.Slice_Number (I)));
          end loop;
    

    ...并在声明块中返回Output

          return Output;
       end;
    
    end Split;
    

    调用Split,它会返回一个你事先不知道长度的StrArray,你可以使用constraint by initial value的技术:

    declare
       T : constant StrArray := Split ("goodbye  world ", " ");
    begin
       for J in T'Range loop
          Ada.Text_IO.Put_Line ("'"
                                  & Ada.Strings.Unbounded.To_String (T (J))
                                  & "'");
       end loop;
    end;
    

    【讨论】:

    • 谢谢大家,它有效。现在只是想知道,如何知道调用 Split() 的函数中输出的长度,以便声明一个 StrArray 来保存输出。 (似乎在 ADA 中我做不到:Split("line",",")'Range)干杯。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    • 1970-01-01
    相关资源
    最近更新 更多