โŒ About FreshRSS

Reading view

There are new articles available, click to refresh the page.

Coding Ada: strings (iii) โ€“ arrays of strings

The problem with strings in Ada is that they just donโ€™t play nicely. As we have seen in previous posts, strings in Ada are either fixed, or unbounded. Now creating an array of strings in other languages isnโ€™t that hard, nor is it in Ada โ€“ some things are just beyond its scope. Now by an array of strings, I mean a structure that could hold something like a dictionary of words. So how do we go about this?

The first example below creates a type, lexicon, with is a 5 element array of strings, 3 characters in length (so 5 three letter words). The variable words is then an instantiation of lexicon, which is assigned five three letter words. Itโ€™s not really possible to use the term string without the constraints (1..3). This is because of the fact that strings in Ada are fixed length โ€“ and it means all the strings assigned to words will have to be of length 3.

type lexicon is array(1..5) of string(1..3);
words : lexicon := ("gum","sin","cry","lug","fly");

It is also not possible to make the constraint larger, e.g. (1..10), and use words or variable length, e.g. โ€œgumโ€, โ€œhouseflyโ€, โ€œstarโ€. This will cause a constraint error (the word star would have to be specified as โ€œstar โ€œ, with 6 spaces filling out the word). The alternative is to unbounded strings, but they come with their own baggage. Consider the following code, changing the string to an unbounded_string.

type lexicon is array(1..5) of unbounded_string;
words : lexicon := ("gum","sin","cry","lug","star");

Compile this, and it will produce a series of errors of the form:

file.adb:10:24: expected private type "Ada.Strings.Unbounded.Unbounded_String"
file.adb:10:24: found a string type

This means that when it tried to assign the words, it considered โ€œgumโ€ to be a string, NOT an unbounded_string. The declaration of lexicon works fine if reading directly from a file, but not predefined strings. The fix? Not pretty, because the strings have to be converted to unbound strings using the function to_unbounded_string().

words : lexicon :=(to_unbounded_string("gum"),to_unbounded_string("sin"),to_unbounded_string("cry"),to_unbounded_string("lug"),to_unbounded_string("star"));

Messy right? There is one way of cleaning up this code and that is providing an alias for the function name to_unbounded_string(). Here is how that is done, renaming the function to tub().

function tub(Source : String) return unbounded_string renames ada.strings.unbounded.to_unbounded_string;

Then the code below it becomes:

type lexicon is array(1..5) of unbounded_string;
words : lexicon := (tub("gum"),tub("sin"),tub("cry"),tub("lug"),tub("star"));

Not perfect, but then that is Ada and strings for you.

spqr

Coding Ada: strings (iii) โ€“ arrays of strings

The problem with strings in Ada is that they just donโ€™t play nicely. As we have seen in previous posts, strings in Ada are either fixed, or unbounded. Now creating an array of strings in other languages isnโ€™t that hard, nor is it in Ada โ€“ some things are just beyond its scope. Now by an array of strings, I mean a structure that could hold something like a dictionary of words. So how do we go about this?

The first example below creates a type, lexicon, with is a 5 element array of strings, 3 characters in length (so 5 three letter words). The variable words is then an instantiation of lexicon, which is assigned five three letter words. Itโ€™s not really possible to use the term string without the constraints (1..3). This is because of the fact that strings in Ada are fixed length โ€“ and it means all the strings assigned to words will have to be of length 3.

type lexicon is array(1..5) of string(1..3);
words : lexicon := ("gum","sin","cry","lug","fly");

It is also not possible to make the constraint larger, e.g. (1..10), and use words or variable length, e.g. โ€œgumโ€, โ€œhouseflyโ€, โ€œstarโ€. This will cause a constraint error (the word star would have to be specified as โ€œstar โ€œ, with 6 spaces filling out the word). The alternative is to unbounded strings, but they come with their own baggage. Consider the following code, changing the string to an unbounded_string.

type lexicon is array(1..5) of unbounded_string;
words : lexicon := ("gum","sin","cry","lug","star");

Compile this, and it will produce a series of errors of the form:

file.adb:10:24: expected private type "Ada.Strings.Unbounded.Unbounded_String"
file.adb:10:24: found a string type

This means that when it tried to assign the words, it considered โ€œgumโ€ to be a string, NOT an unbounded_string. The declaration of lexicon works fine if reading directly from a file, but not predefined strings. The fix? Not pretty, because the strings have to be converted to unbound strings using the function to_unbounded_string().

words : lexicon :=(to_unbounded_string("gum"),to_unbounded_string("sin"),to_unbounded_string("cry"),to_unbounded_string("lug"),to_unbounded_string("star"));

Messy right? There is one way of cleaning up this code and that is providing an alias for the function name to_unbounded_string(). Here is how that is done, renaming the function to tub().

function tub(Source : String) return unbounded_string renames ada.strings.unbounded.to_unbounded_string;

Then the code below it becomes:

type lexicon is array(1..5) of unbounded_string;
words : lexicon := (tub("gum"),tub("sin"),tub("cry"),tub("lug"),tub("star"));

Not perfect, but then that is Ada and strings for you.

spqr

โŒ