Last modified on 4 March 2014, at 18:04

Ada Programming/Strings


Ada Lovelace 1838.jpg

Ada supports three different types of strings. Each string type is designed to solve a different problem.

In addition, every string type is implemented for each available Characters type (Character, Wide_Character, Wide_Wide_Character) giving a complement of nine combinations.

Fixed-length string handlingEdit

Fixed-Length Strings (the predefined type String) are arrays of Character, and consequently of a fixed length. Since String is an indefinite subtype the length does not need to be known at compile time — the length may well be calculated at run time. In the following example the length is calculated from command-line argument 1:

X : String := Ada.Command_Line.Argument (1);

However once the length has been calculated and the string has been created the length stays constant. Try the following program which shows a typical mistake:

File: show_commandline_1.adb (view, plain text, download page, browse all)
with Ada.Text_IO;
with Ada.Command_Line;

procedure Show_Commandline_1 is

   package T_IO renames Ada.Text_IO;
   package CL   renames Ada.Command_Line;

   X : String := CL.Argument (1);

begin
   T_IO.Put ("Argument 1 = ");
   T_IO.Put_Line (X);

   X := CL.Argument (2);

   T_IO.Put ("Argument 2 = ");
   T_IO.Put_Line (X);
end Show_Commandline_1;

The program will only work when the 1st and 2nd parameter have the same length. This is even true when the 2nd parameter is shorter. There is neither an automatic padding of shorter strings nor an automatic truncation of longer strings.

Having said that, the package Ada.Strings.Fixed contains a set of procedures and functions for Fixed-Length String Handling which allows padding of shorter strings and truncation of longer strings.

Try the following example to see how it works:

File: show_commandline_2.adb (view, plain text, download page, browse all)
with Ada.Text_IO;
with Ada.Command_Line;
with Ada.Strings.Fixed;

procedure Show_Commandline_2 is

   package T_IO renames Ada.Text_IO;
   package CL   renames Ada.Command_Line;
   package S    renames Ada.Strings;
   package SF   renames Ada.Strings.Fixed;

   X : String := CL.Argument (1);

begin
   T_IO.Put ("Argument 1 = ");
   T_IO.Put_Line (X);

  SF.Move (
     Source  => CL.Argument (2),
     Target  => X,
     Drop    => S.Right,
     Justify => S.Left,
     Pad     => S.Space);

   T_IO.Put ("Argument 2 = ");
   T_IO.Put_Line (X);
end Show_Commandline_2;

Bounded-length string handlingEdit

Bounded-Length Strings can be used when the maximum length of a string is known and/or restricted. This is often the case in database applications where only a limited number of characters can be stored.

Like Fixed-Length Strings the maximum length does not need to be known at compile time — it can also be calculated at runtime — as the example below shows:

File: show_commandline_3.adb (view, plain text, download page, browse all)
with Ada.Text_IO;
with Ada.Command_Line;
with Ada.Strings.Bounded;

procedure Show_Commandline_3 is

   package T_IO renames Ada.Text_IO;
   package CL   renames Ada.Command_Line;

   function Max_Length (
      Value_1 : Integer;
      Value_2 : Integer)
   return
      Integer
   is
      Retval : Integer;
   begin
      if Value_1 > Value_2 then
         Retval := Value_1;
      else
         Retval := Value_2;
      end if;
      return Retval;
   end Max_Length;

   pragma Inline (Max_Length);

   package SB
   is new Ada.Strings.Bounded.Generic_Bounded_Length (
       Max => Max_Length (
                  Value_1 => CL.Argument (1)'Length,
                  Value_2 => CL.Argument (2)'Length));

   X :  SB.Bounded_String
     := SB.To_Bounded_String (CL.Argument (1));

begin
   T_IO.Put ("Argument 1 = ");
   T_IO.Put_Line (SB.To_String (X));

   X := SB.To_Bounded_String (CL.Argument (2));

   T_IO.Put ("Argument 2 = ");
   T_IO.Put_Line (SB.To_String (X));
end Show_Commandline_3;

You should know that Bounded-Length Strings have some distinct disadvantages. Most noticeable is that each Bounded-Length String is a different type which makes converting them rather cumbersome. Also a Bounded-Length String type always allocates memory for the maximum permitted string length for the type. The memory allocation for a Bounded-Length String is equal to the maximum number of string "characters" plus an implementation dependent number containing the string length (each character can require allocation of more than one byte per character, depending on the underlying character type of the string, and the length number is 4 bytes long for the Windows GNAT Ada compiler v3.15p, for example).

Unbounded-length string handlingEdit

Last but not least there is the Unbounded-Length String. In fact: If you are not doing embedded or database programming this will be the string type you are going to use most often as it gives you the maximum amount of flexibility.

As the name suggest the Unbounded-Length String can hold strings of almost any length — limited only to the value of Integer'Last or your available heap memory. This is because Unbounded_String type is implemented using dynamic memory allocation behind the scenes, providing lower efficiency but maximum flexibility.

File: show_commandline_4.adb (view, plain text, download page, browse all)
with Ada.Text_IO;
with Ada.Command_Line;
with Ada.Strings.Unbounded;

procedure Show_Commandline_4 is

   package T_IO renames Ada.Text_IO;
   package CL   renames Ada.Command_Line;
   package SU   renames Ada.Strings.Unbounded;

   X :  SU.Unbounded_String 
     := SU.To_Unbounded_String (CL.Argument (1));

begin
   T_IO.Put ("Argument 1 = ");
   T_IO.Put_Line (SU.To_String (X));

   X := SU.To_Unbounded_String (CL.Argument (2));

   T_IO.Put ("Argument 2 = ");
   T_IO.Put_Line (SU.To_String (X));
end Show_Commandline_4;

As you can see the Unbounded-Length String example is also the shortest (discarding the first example, which is buggy) — this makes using Unbounded-Length Strings very appealing.

See alsoEdit

WikibookEdit

Ada 95 Reference ManualEdit

Ada 2005 Reference ManualEdit