Ada String Handling

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

Below is my code where I need to parse variable sized strings, not just 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;

      

+2


source to share


1 answer


The fact that it GNAT.String_Split

uses String

doesn't mean that yours StrArray

should. And you need to serve input strings with varying numbers of tokens, so start by declaring StrArray

as an unbounded array type:

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

      

Now it Split

starts like this:

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

      

(we won't announce it yet Output

, and we won't need it Count

, and I had to google to find out what String_Split

is the GNAT utility package).

The first thing to do is split the input string so we know how big it should be Output

(by the way, do you really want to Single

?):

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

      

Now we can declare Output

with Slice_Count

. Note the conversion to Natural

(not Positive

; if the input is empty, 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 with Output

tokens. AdaCore decided to implement Slice_Number

as new Natural

, not as a subtype Natural

, so we need a transformation.

      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

to the ad block.

      return Output;
   end;

end Split;

      

To call Split

that will return the StrArray

length of which you don't know in advance, you can use the start-value constraint technique :

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;

      

+7


source







All Articles