在Ada中的字符串数组

6

我有一个Ada95程序,需要创建一个字符串数组。这个数组可以包含可变长度的字符串。

例如: 我声明了一个数组,所有索引都可以存储大小为50的字符串。当我将更小的字符串分配给上述数组时,会出现“约束错误”。

代码:

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

我尝试创建Unbounded_Strings数组,但这也无法工作。有人可以告诉我如何将“12345”存储在上述字符串数组中吗?


解决方案是使用 Unbounded_String。请展示您尝试创建 Unbounded_String 数组的代码。String 类型不允许变长字符串。 - ajb
对于Unbounded_String,我使用了以下代码: input_array := array(1..5) of Unbounded_String;然后我得到了以下错误:"expected private type "Ada.Strings.Unbounded.Unbounded_String"。然后我尝试将代码更改为: input_array:array(1..5) of Ada.Strings.Unbounded.Unbounded_String;现在我无法将值分配给input_array(1)。 - Romil Agrawal
如果您尝试直接使用:=与字符串文字一起使用,请查看我的答案。总的来说,请更具体地说明您遇到的问题。在StackOverflow上,仅说“我无法做到这一点”或“它不起作用”是不够的,因为我们不能读取您的思维。相反,请发布您尝试的代码和收到的错误消息。 - ajb
4个回答

8

如果您使用Unbounded_String,则无法直接将字符串字面量分配给它。字符串字面量可以有类型StringWide_StringWide_Wide_String,但没有其他类型;而在Ada中赋值通常要求目标和源具有相同的类型。要将String转换为Unbounded_String,您需要调用To_Unbounded_String函数:

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;

您可以使用use子句缩短名称;其他一些程序员可能会定义自己的重命名函数,甚至可能使用一元运算符"+"
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;

并不是每个人都喜欢这种风格。


谢谢ajb。你的代码有效。我为无界字符串编写了以下代码。代码: 过程任意名称是 输入数组:数组(1..5)的Ada.Strings.Unbounded.Unbounded_String; 开始 输入数组(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); 结束任何名称;但是我得到了这些错误: “length”属性的前缀可能不是私有类型 “first”属性的前缀可能不是私有类型 “last”属性的前缀可能不是私有类型 - Romil Agrawal
"Length" 在 "Unbounded_String" 上不起作用。要使用 "Unbounded_String",必须使用 RM 中定义的过程和函数。您不能使用用于 "String" 或其他 "array" 类型的东西,因为 "Unbounded_String" 不是数组。请阅读 RM 文档 此处 - ajb
1
在Ada中,赋值通常要求目标和源是相同的类型。您需要澄清“通常”是什么意思? - TamaMcGlinn
使用 + 运算符来重命名转换函数是 Ada 的习惯用法吗?以前没有见过。 - Rodeo

2

您可以使用Ada.Strings.Unbounded,这里有演示 (点击此处);或者您也可以使用静态的分层数组,这里有演示(点击此处)。后一种方法使用一个别名组件的数组,每个组件的长度可能不同。

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
      );

1

我从实例化容器包中获得了很多乐趣,例如:

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

相对于其他很多编程语言轻松地处理字符串,这仍然有点棘手,但还好。

从根本上讲,Ada是一种设计用于不使用堆(完全没有 :-))就可以使用的语言。大多数其他语言如果没有堆会崩溃。


1

Ada中的字符串是固定长度的字符数组。为了使用可变长度的字符串(当需要字符串数组时,例如名称数组,每个名称长度不同),可以将每个单独的字符串声明为Unbounded_String。唯一的注意事项是这会从堆内存分配空间。下面是一个完整的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;

这将产生以下输出:


$ ./arrayAda
Sunday   Monday   Tuesday   Wednesday   Thursday   Friday   Saturday

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接