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
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:
renamesAda.Command_Line; X : String := CL.Argument (1);
beginT_IO.Put ("Argument 1 = "); T_IO.Put_Line (X); X := CL.Argument (2); T_IO.Put ("Argument 2 = "); T_IO.Put_Line (X);
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.
Try the following example to see how it works:
renamesAda.Strings.Fixed; X : String := CL.Argument (1);
beginT_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);
Bounded-length string handling
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:
functionMax_Length ( Value_1 : Integer; Value_2 : Integer)
isRetval : Integer;
ifValue_1 > Value_2
thenRetval := Value_1;
elseRetval := Value_2;
newAda.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));
beginT_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));
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
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.
renamesAda.Strings.Unbounded; X : SU.Unbounded_String := SU.To_Unbounded_String (CL.Argument (1));
beginT_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));
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.
Ada 95 Reference Manual
- 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)