Ada Programming/Strings
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 handling
editFixed-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:
with
Ada.Text_IO;with
Ada.Command_Line;procedure
Show_Commandline_1is
package
T_IOrenames
Ada.Text_IO;package
CLrenames
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:
with
Ada.Text_IO;with
Ada.Command_Line;with
Ada.Strings.Fixed;procedure
Show_Commandline_2is
package
T_IOrenames
Ada.Text_IO;package
CLrenames
Ada.Command_Line;package
Srenames
Ada.Strings;package
SFrenames
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 handling
editBounded-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:
with
Ada.Text_IO;with
Ada.Command_Line;with
Ada.Strings.Bounded;procedure
Show_Commandline_3is
package
T_IOrenames
Ada.Text_IO;package
CLrenames
Ada.Command_Line;function
Max_Length ( Value_1 : Integer; Value_2 : Integer)return
Integeris
Retval : Integer;begin
if
Value_1 > Value_2then
Retval := Value_1;else
Retval := Value_2;end
if
;return
Retval;end
Max_Length;pragma
Inline (Max_Length);package
SBis
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 handling
editLast 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.
with
Ada.Text_IO;with
Ada.Command_Line;with
Ada.Strings.Unbounded;procedure
Show_Commandline_4is
package
T_IOrenames
Ada.Text_IO;package
CLrenames
Ada.Command_Line;package
SUrenames
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 (disregarding the buggy first example) — this makes using Unbounded-Length Strings very appealing.
See also
editWikibook
editAda 95 Reference Manual
edit- 2.6: String Literals [Annotated]
- 3.6.3: String Types [Annotated]
- A.4.3: Fixed-Length String Handling [Annotated]
- A.4.4: Bounded-Length String Handling [Annotated]
- A.4.5: Unbounded-Length String Handling [Annotated]