2016-09-28 11 views
2

は、私は私のコードの後半での値を設定したい文字列lx : Stringを持っているが、私はまた、エラーunconstrained element type in array declarationを投げている文字列配列L_array : array (1 .. user_size) of String;を、持っている文字列を初期値で初期化する必要があるのはなぜですか?

エラーunconstrained subtype not allowed (need initialization) provide initial value or explicit array boundsを取得しています。値はテキストファイルから読み込まれるため、これを初期化することはできません。これらの値を後で設定したい場合は、これについて何をすべきですか?

答えて

8

実際には2つの質問がありますが、原因は同じです。Stringは、作成時にサイズが固定(つまり制約されている)である必要があります。

サイズがわかっていて(array of Stringの場合)、すべてStringは同じサイズですが、それらを制約するのは簡単で、それ以上のコメントは必要ありません。

長さが不明なStringが何を意味するかを考えてみましょう:不明なストレージ要件。 1つのアプローチは、ポインタまたはアクセスタイプを使用し、ストリングを保持するためにストレージを割り当て、後で解放することを覚えておくことです。他の言語と同じように、バグ、メモリリークなどの可能性があります。サイズの上限を推測し、バッファオーバーフローの可能性を開かせる代替アプローチもあります。あなたは他の言語のようにAdaでそれをすることができますが、ベストプラクティスではありません。

Adaは、問題を最小限に抑えることを目的として、これらの両方のパターンをそれぞれUnbounded_StringBounded_Stringという形で提供します。しかし、彼らはStringよりも使い勝手が悪いです。

これらの抽象化のsomewhat intense discussionは、だから私はあなただけStringでこれら二つのタスクを行うことができる方法を提案しますcomp.lang.adaニュースグループ(それにGoogleグループのゲートウェイを使用するための私の謝罪)

にあります。後で上の値を設定し、単一の文字列lx : Stringの場合には


、答えは簡単です:ちょうどその値で初期化、後でStringを宣言します。代わり

lx : String; 

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

使用(典型的には、ループ本体で)宣言ブロックの:

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

ストリングlxスコープから外れendで、それはから、正しいサイズの(新たに作成され初期化、次回はあなたが各メンバーは異なるサイズを持っている場合Array of Stringがより困難である。


declareブロックに到達し、Bounded_StringまたはUnbounded_Stringは有用な候補です。

ただし、代替アプローチ(Ada-2005以降)では、配列の代わりにAda.Containersパッケージを使用することになります。これらは明確で無限の味で来る、あなたは無限のコンテナに異なるサイズのメンバーを保管したい。ベクトルとして具体的にAda.Containers.Indefinite_Vectorsは、配列と同様に索引付けすることができます。

このアプローチは、C++でstd_vectorを使用するのと類似しています。実際、標準テンプレートライブラリはもともとAda用であり、後でC++に適合しました。

Ada-2005より前は、Ada.Containersは言語の一部ではありませんでしたが、Boochコンポーネント(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; 
4

Adaの文字列型は、 type String is array(Positive range <>) of Characterと定義されています。変数を宣言するための初期範囲がgiven an initial string or given a range constraintである必要があります。それ以外の場合、コンパイラはオブジェクトの大きさを知ることができません。

ファイルからの読み取り方法は、Rosettacodeのサンプルをご覧ください。

関連する問題