为什么字符串需要用初始值初始化?

时间:2016-09-28 17:01:07

标签: arrays string ada

我有一个字符串lx : String,我希望稍后在我的代码中设置值,但我收到错误unconstrained subtype not allowed (need initialization) provide initial value or explicit array bounds

我还有一个字符串数组L_array : array (1 .. user_size) of String;,它会抛出错误unconstrained element type in array declaration。我无法初始化它,因为从文本文件中读取值。如果我想稍后设置这些值,我该怎么办?

2 个答案:

答案 0 :(得分:8)

这里确实存在两个问题,但具有相同的根本原因:String在创建时必须固定其大小(即约束)。

如果您知道它的大小,并且(在array of String的情况下)所有String的大小都相同,那么限制它们很容易,无需进一步评论。

考虑未知长度的String意味着什么:未知的存储要求。一种方法是使用指针或访问类型,分配存储来保存字符串,并记住以后释放它。这样,就像在其他语言中一样,有可能存在错误,内存泄漏等。猜测大小上限的替代方法也是如此,这开启了缓冲区溢出的可能性。你可以在Ada中这样做,就像在其他语言中一样,但是......不是最佳实践。

Ada分别以Unbounded_StringBounded_String的形式提供这两种模式的抽象,旨在最大限度地减少问题。但它们的使用仍然不如String

somewhat intense discussion新闻组中有comp.lang.ada个这些抽象(我对使用Google网上论坛网站道歉)

因此,我建议您只使用String执行这两项任务的方法。

对于稍后设置值的单个字符串lx : String的情况,答案很简单:稍后再声明String,使用该值初始化。而不是

lx : String;

...
lx := Read(My_File);
Process_String(lx);

使用声明块(通常在循环体中):

...    
declare
   lx : String := Read(My_File);
begin
   Process_String(lx);
end;

end,字符串lx超出范围,并且会在下次到达declare块时从初始化开始重新创建(正确的大小)。

如果每个成员的尺寸不同,则Array of String会更加困难,Bounded_StringUnbounded_String是有用的候选人。

但另一种方法(自Ada-2005以来)将使用Ada.Containers包而不是数组。它们有Definite和Indefinite风格,你想要一个Indefinite容器来存储不同大小的成员。具体而言,Ada.Containers.Indefinite_Vectors作为Vector可以索引类似于数组。

这种方法与在C ++中使用std_vector有相似之处,实际上标准模板库最初是用于Ada,后来又适用于C ++。

在Ada-2005之前,Ada.Containers不是该语言的一部分,但你会使用外部库中的等价物,例如(我认为)Booch Components(Grady Booch)。

首发:

with Ada.Containers.Indefinite_Vectors;
with Ada.Text_IO; 

procedure String_Vector is

User_Size : constant natural := 10;
subtype Index is natural range 1 .. User_Size;

-- Indefinite_Vectors is a generic package. 
-- You can't use it directly, instantiate it with index and content types
package String_Holder is new Ada.Containers.Indefinite_Vectors(Index,String);
-- make String_Holder operations visible
use String_Holder; 

LV       : String_Holder.Vector;        -- initially empty
L_Vector : String_Holder.Vector :=      -- initialise to size with empty elements
          To_Vector(Ada.Containers.Count_Type(User_Size)); 


begin
   L_Vector.Replace_Element(1,"hello");
   LV.Append("world");
   Ada.Text_IO.Put_Line(L_Vector(1) & " " & LV(1));
end String_Vector;

答案 1 :(得分:4)

Ada的String类型定义为 type String is array(Positive range <>) of Character。这需要一个初始范围来声明一个变量,由given an initial string or given a range constraint,否则编译器将无法知道该对象有多大。

请查看Rosettacode处的示例,了解如何从文件中读取。