Ada中的字符串处理 [英] String handling in Ada

查看:141
本文介绍了Ada中的字符串处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Ada中定义一个字符串数组,以存储可变大小的字符串。
我的问题是我必须预先定义我在编译时不知道的Strings的大小,并且使用
Unbounded_Strings时String_Split.Create将无法工作,因为它需要Standard.String。



下面是我的代码,在这里我需要能够解析大小可变的字符串,而不仅仅是
固定长度的4。 / p>

预先感谢。

  type StrArray是array(1 .. 7)的String(1..4); 

函数Split(Line:String; Sep:String)return StrArray是
令牌:String_Split.Slice_Set;
输出:StrArray;
计数:自然:= 0;
开始
String_Split.Create(s =>令牌,
从=>行,
分隔符=> Sep,
模式=> String_Split.Single );

对于1中的I .. String_Split.Slice_Count(令牌)循环
Count:= Count + 1;
Output(Count):= String_Split.Slice(Tokens,I); -也不确定如何将Slice_Count转换为Integer!
结束循环;

返回输出;

结束分割;


解决方案

GNAT的事实。 String_Split 使用 String 并不意味着您的 StrArray 必须使用。并且您需要迎合具有不同数量令牌的输入字符串,因此首先将 StrArray 声明为不受约束的数组类型:

 类型StrArray是Ada.Strings.Unbounded.Unbounded_String;的数组(正范围<>)

现在 Split 开始如下:

 函数Split(Line:String; Sep:String)return StrArray是
令牌:GNAT.String_Split.Slice_Set;
开始

(我们不能声明 Output ,我们不需要 Count ;我不得不去Google找出 String_Split 是GNAT实用程序包。)



要做的第一件事是拆分输入行,以便我们知道 Output 必须是(顺便说一句,您真的要 Single 吗?):

  GNAT.String_Split.Create(S =>令牌,
从=>行,
分隔符=> Sep,
模式=> GNAT .String_Split.Single);

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

 声明
输出:StrArray
(1 ..Natural(GNAT.String_Split.Slice_Count(Tokens)));
开始

现在填充输出与令牌。 AdaCore选择将 Slice_Number 实现为 new Natural ,而不是实现为 Natural 的子类型。 code>,这就是为什么我们需要转换。

  for Output'Range loop中的I 
输出(I):=
Ada.Strings.Unbounded.To_Unbounded_String
(GNAT.String_Split.Slice
(令牌,GNAT.String_Split.Slice_Number(I)));
结束循环;

...并返回 Output

 返回输出; 
结尾;

结束分割;

要调用 Split 返回 StrArray 的长度,您事先不知道它的长度,可以使用受初始值限制

  declare 
T:常量StrArray:=拆分(再见世界,);
在T'Range循环中以J开始

Ada.Text_IO.Put_Line('
& Ada.Strings.Unbounded.To_String(T(J))
&');
结束循环;
结尾;


I'm trying to define an array of Strings in Ada to store Strings of variable size. The problem I have is that I must pre-define the size of my Strings which I don't know at compile time, and with the Unbounded_Strings the String_Split.Create wouldn't work, as it requires Standard.String.

Below is my code, where I need to be able to parse Strings of variable size, and not just the fixed length 4.

Thanks in advance.

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;

解决方案

The fact that GNAT.String_Split uses String doesn’t mean that your StrArray has to. And you need to cater for input strings with varying numbers of tokens, so begin by declaring StrArray as an unconstrained array type:

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

Now Split begins like this:

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

(we can’t declare Output yet, and we won’t need Count; and I had to go to Google to find out that String_Split is a GNAT utility package).

The first thing to do is to split the input line, so that we know how large Output needs to be (by the way, do you really want Single?):

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

Now we can declare Output using the Slice_Count. Note the conversion to Natural (not Positive; if the input is an empty string, there will be no tokens, so the output will be an empty array, range 1 .. 0).

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

Now fill Output with the tokens. AdaCore chose to implement Slice_Number as new Natural, rather than as a subtype of Natural, which is why we need the conversion.

      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;

... and return Output, within the declare block.

      return Output;
   end;

end Split;

To call Split, which is going to return a StrArray whose length you don’t know beforehand, you can use the technique of 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;

这篇关于Ada中的字符串处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆