我有一个字符串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
。我无法初始化它,因为从文本文件中读取值。如果我想稍后设置这些值,我该怎么办?
答案 0 :(得分:8)
这里确实存在两个问题,但具有相同的根本原因:String
在创建时必须固定其大小(即约束)。
如果您知道它的大小,并且(在array of String
的情况下)所有String
的大小都相同,那么限制它们很容易,无需进一步评论。
考虑未知长度的String
意味着什么:未知的存储要求。一种方法是使用指针或访问类型,分配存储来保存字符串,并记住以后释放它。这样,就像在其他语言中一样,有可能存在错误,内存泄漏等。猜测大小上限的替代方法也是如此,这开启了缓冲区溢出的可能性。你可以在Ada中这样做,就像在其他语言中一样,但是......不是最佳实践。
Ada分别以Unbounded_String
和Bounded_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_String
或Unbounded_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处的示例,了解如何从文件中读取。