6

I have a program in Ada95, in which I have to create an array of strings. This array can contain strings of variable length.

Example: I have declared the array in which all the indexes can store strings of size 50. When I assign a smaller string to the above array, I get "Constraint Error".

Code:

procedure anyname is
    input_array : array(1..5) of String(1..50);
begin
    input_array(1):="12345";
end anyname;

I have tried to create the array of Unbounded_Strings. But that doesn't work either. Can anyone tell me how to store this "12345" in the above string array?

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
Romil Agrawal
  • 61
  • 1
  • 3
  • The solution is to use `Unbounded_String`. Please show the code where you tried to create an array of `Unbounded_String`. The `String` type does not allow for strings of variable length. – ajb Nov 01 '14 at 00:01
  • For Unbounded_String, I used the following code: input_array := array(1..5) of Unbounded_String; I then got the following error: "expected private type "Ada.Strings.Unbounded.Unbounded_String". Then I tried to change the code to: input_array : array(1..5) of Ada.Strings.Unbounded.Unbounded_String; Now I cannot assign the values to the input_array(1) – Romil Agrawal Nov 01 '14 at 02:05
  • If you tried to use `:=` directly with a string literal, please see my answer. In general, please be more specific about what problems you are having. Saying things like "I cannot do this" or "it doesn't work" are not good enough on StackOverflow because we are not mind readers. Instead, post the code you tried and the error message you got. – ajb Nov 01 '14 at 19:20

4 Answers4

8

If you use Unbounded_String, you cannot assign a string literal to it directly. String literals can have type String, Wide_String, or Wide_Wide_String, but nothing else; and assignment in Ada usually requires that the destination and source be the same type. To convert a String to an Unbounded_String, you need to call the To_Unbounded_String function:

procedure anyname is
    input_array : array(1..5) of Ada.Strings.Unbounded.Unbounded_String;
begin
    input_array(1) := Ada.Strings.Unbounded.To_Unbounded_String ("12345");
end anyname;

You can shorten the name by using a use clause; some other programmers might define their own renaming function, possibly even using the unary "+" operator:

function "+" (Source : String) return Ada.Strings.Unbounded.Unbounded_String
    renames Ada.Strings.Unbounded.To_Unbounded_String;

procedure anyname is
    input_array : array(1..5) of Ada.Strings.Unbounded.Unbounded_String;
begin
    input_array(1) := +"12345";  -- uses renaming "+" operator
end anyname;

Not everyone likes this style.

ajb
  • 31,309
  • 3
  • 58
  • 84
  • Thanks ajb. Your code works. I wrote the following code for unbounded string. code: procedure anyname is input_array : array(1..5) of Ada.Strings.Unbounded.Unbounded_String; begin input_array(1) := Ada.Strings.Unbounded.To_Unbounded_String ("12345"); put_line(input_array(1)'Length); put_line(input_array(1)'First); put_line(input_array(1)'Last); end any name; But I am getting these error: Prefix for 'length' attribute may not be private type Prefix for 'first' attribute may not be private type Prefix for 'last' attribute may not be private type – Romil Agrawal Nov 01 '14 at 21:56
  • `'Length` does not work on `Unbounded_String`. To use `Unbounded_String`, you have to use the procedures and functions defined in the RM. You can't use the stuff you use for `String` or other `array` types, because an `Unbounded_String` is not an array. Please read the RM documentation [here](http://www.ada-auth.org/standards/12rm/html/RM-A-4-5.html) – ajb Nov 01 '14 at 22:55
  • 1
    "assignment in Ada usually requires that the destination and source be the same type" Could you clarify the "usually"? – TamaMcGlinn Sep 17 '18 at 10:32
  • Is using the `+` operator to rename conversion functions an Ada idiom? Haven't seen that before. – Rodeo Feb 22 '20 at 19:55
2

You can use Ada.Strings.Unbounded, illustrated here, or you can use a static ragged array, illustrated here. The latter approach uses an array of aliased components, each of which may have a different length.

type String_Access is access constant String;

String_5: aliased constant String := "12345";
String_6: aliased constant String := "123456";
String_7: aliased constant String := "1234567";
...

Input_Array: array (1..N) of
   String_Access :=
      (1 => String_5'Access,
       2 => String_6'Access,
       3 => String_7'Access,
       -- etc. up to N
      );
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
1

Strings in Ada are arrays of characters of fixed length. In order to use strings of variable length (which may often be the case when arrays of strings are needed, e.g. arrays of names, each name being of variable length), each individual string may be declared as an Unbounded_String. The only caveat is that this allocates from the heap memory. Below is a complete example of an array of strings in Ada.

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;

procedure arrayAda is
type DaysArray is array(1..7) of Unbounded_String;
days: DaysArray;
begin
    days(1):=To_Unbounded_String("Sunday");
    days(2):=To_Unbounded_String("Monday");
    days(3):=To_Unbounded_String("Tuesday");
    days(4):=To_Unbounded_String("Wednesday");
    days(5):=To_Unbounded_String("Thursday");
    days(6):=To_Unbounded_String("Friday");
    days(7):=To_Unbounded_String("Saturday");
    for index in 1..7 loop
        Put(days(index));
        Put("   ");
    end loop;
end arrayAda;

This produces the following output:

$ ./arrayAda
Sunday   Monday   Tuesday   Wednesday   Thursday   Friday   Saturday
Adriana
  • 41
  • 4
1

I've had a lot of joy from instantiating a container package, e.g.:

package String_Vectors is
   new Ada.Containers.Indefinite_Vectors (Positive, String);

It's still a bit fiddly, compared to how easy it is to mess about with strings in a lot of other programming languages, but it's okay.

Fundamentally, Ada is a language designed to be usable without using the heap (at all :-) Most other languages would fall down in a, well, a heap, without the heap.

debater
  • 466
  • 6
  • 11