Coding Ada: strings (iv) – unbounded to string

As mentioned before, strings in Ada can be tricky. Normal strings are fixed in length, and Ada is very stringent about this. Consider a piece of code like this:

with ada.Text_IO; use Ada.Text_IO;
with ada.strings.unbounded; use ada.strings.unbounded;

procedure ustr2strfail is
   function tub(Source : String) return unbounded_string renames ada.strings.unbounded.to_unbounded_string;
   type lexicon is array(1..10) of unbounded_string;
   words : lexicon := (tub("gum"),tub("sin"),tub("cry"),
           tub("lug"),tub("star"),tub("fault"),tub("sleeper"),
           tub("a"),tub("vader"),tub("nordic"));
   aword : string(1..10);
begin
   aword := to_string(words(7));
   put(aword);
end ustr2strfail;

This will compile fine, however when it runs, the following error will propogate:

raised CONSTRAINT_ERROR : ustr2strfail.adb:12 length check failed

This means that although the unbounded string is converted to a string using the function to_string(), it only works if the length of the unbounded string equals the length of the string aword. So in the code above, aword has a length of 10, and when an attempt is made to assign it the unbounded string, “sleeper”, it fails. It would work if sleeper was padded out with 3 spaces after it. How to fix this? Do exactly that, pad the words. Here is a subroutine that does this:

with ada.Text_IO; use Ada.Text_IO;
with ada.strings.unbounded; use ada.strings.unbounded;
with ada.strings.unbounded.Text_IO; use ada.strings.unbounded.Text_IO;
with ada.strings.fixed; use ada.strings.fixed;

procedure ustr2str is
   subtype string10 is string(1..10);
   R : string10;
   function tub(Source : String) return unbounded_string renames ada.strings.unbounded.to_unbounded_string;
   type lexicon is array(1..10) of unbounded_string;
   words : lexicon := (tub("gum"),tub("sin"),tub("cry"),
           tub("lug"),tub("star"),tub("fault"),tub("sleeper"),
           tub("a"),tub("vader"),tub("nordic"));

   function padString(V: unbounded_string) return string10 is
      temp : constant string := to_string(V);
      res : string10;
   begin
      ada.strings.fixed.move(temp, res, drop=>ada.strings.right);
      return res;
   end padString;

begin
   R := padString(words(7));
   put(R);
end ustr2str;

It uses the procedure move(), from the ada.strings.fixed package. It has the following basic form:

procedure Move (Source  : in  String;
                Target  : out String;
                Drop    : in  Truncation := Error;
                Justify : in  Alignment  := Left;
                Pad     : in  Character  := Space);

The procedure move() copies characters from Source to Target. If Source has the same length as Target, then the effect is to assign Source to Target. If Source is shorter than Target then, Justify is used to place the Source into the Target (default = Left). Pad specifies the padding, default is Space. Drop is used if Source is longer than Target.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.