我有一個函數返回一個特定項目的字符串,我需要多次調用該函數並將這些字符串合併爲一個。組合的字符串是有界的。我已經確定在空格字符初始化時填充它,但我一直收到「長度檢查失敗」錯誤。有沒有什麼基本的我在這裏做錯了?Ada字符串串聯
FOR I IN 1..Collection.Size LOOP
Combined_String := combined_string & Tostring(Collection.Book(I));
END LOOP;
我有一個函數返回一個特定項目的字符串,我需要多次調用該函數並將這些字符串合併爲一個。組合的字符串是有界的。我已經確定在空格字符初始化時填充它,但我一直收到「長度檢查失敗」錯誤。有沒有什麼基本的我在這裏做錯了?Ada字符串串聯
FOR I IN 1..Collection.Size LOOP
Combined_String := combined_string & Tostring(Collection.Book(I));
END LOOP;
爲了分配Combined_String,您必須一次性指定完全正確的長度。你不能「建立」一個字符串並在Ada中這樣分配。
沒有看到你的代碼的其餘部分,我認爲Ada.Strings.Unbounded可能是你應該使用的。
Unbounded_String可能是要走的最簡單的方法:
with Ada.Strings.Unbounded;
use Ada.Strings.unbounded;
...
Temp_Unbounded_String : Unbounded_String; -- Is empty by default.
...
for I in 1 .. Collection.Size loop
Append(Temp_Unbounded_String, ToString(Collection.Book(I));
end loop;
然後,如果您需要有結果放置在你的固定長度標準的字符串:
declare
Temp_String : constant String := To_String(Temp_Unbounded_String);
begin
-- Beware! If the length of the Temp_String is greater than that of the
-- fixed-length string, a Constraint_Error will be raised. Some verification
-- of source and target string lengths must be performed!
Combined_String(Temp_String'Range) := Temp_String;
end;
或者,你可以使用阿達.String .Fixed Move()將Unbounded_String帶入目標固定長度字符串的過程:
Ada.Strings.Fixed.Move(To_String(Temp_Unbounded_String), Combined_String);
在這種情況下,如果源字符串「太長」,默認會引發一個Length_Error異常。 Move()還有其他參數可以修改這種情況下的行爲,有關更多詳細信息,請參閱Move上提供的鏈接。
當您可以使用完美大小的數組和字符串時,Ada的效果最佳。這對於99%的字符串使用來說非常有效,但是如果需要逐步從其他字符串逐步構建字符串,則會產生問題。
鑑於這種情況,我真的很想知道爲什麼你需要的組合的字符串。
如果你確實需要這樣做,我知道有兩種好方法可以做到。首先是使用Ada.Strings.Unbounded中的「無界」(動態大小)的字符串,就像Dave和Marc C所建議的那樣。
另一種是使用一些函數式編程(在這種情況下,遞歸)來創建您的固定字符串。例如:
function Combined_String (String_Collection : in String_Collection_Type) return String is
begin
if String_Collection'length = 1 then
return String_Collection(String_Collection'first);
end if;
return String_Collection(String_Collection'first) &
Combined_String (String_Collection'first + 1 .. String_Collection'last);
end Combined_String;
我不知道你使用什麼類型的集合,所以我做了一些猜測。特別是,我假設它是一個不受約束的固定字符串數組。如果不是,則需要將上面的一些代碼替換爲您的容器用來返回其邊界,訪問元素和執行切片的任何內容。
function Next_Line(File : in Ada.Text_IO.File_Type :=
Ada.Text_Io.Standard_Input) return String is
Answer : String(1..256);
Last : Natural;
begin
Ada.Text_IO.Get_Line(File => File,
Item => Answer,
Last => Last);
if Last = Answer'Last then
return Answer & Next_Line(File);
else
return Answer(1..Last);
end if;
end Next_Line;
正如你所看到的,這種方法建立無限*從它的讀取文件長度的字符串(使用Get_Line)。所以,你需要做的,爲了保持你所擁有的是什麼量級的東西:
function Combined_String (String_Collection : in String_Collection_Type)
Return String is
begin
if String_Collection'length = 1 then
Return String_Collection(String_Collection'First).All;
end if;
Recursion:
Declare
Data : String:= String_Collection(String_Collection'First).All;
SubType Constraint is Positive Range
Positive'Succ(String_Collection'First)..String_Collection'Last;
Begin
Return Data & Combined_String(String_Collection(Constraint'Range));
End Recursion;
end Combined_String;
假設String_Collection被定義爲:
Type String_Collection is Array (Positive Range <>) of Access String;
*實際整數限制」範圍,IIRC
我知道這是一個古老的問題,但現在,阿達2012年是出我想我會分享一個成語我一直在使用發現自己...
declare
function Concatenate(i: Collection'index)
is
(tostring(Collection(i) &
if (i = Collection'last) then
("")
else
(Concatenate(i+1))
);
s: string := Concatenate(Collection'first);
begin
Put_Line(s);
end;
鍵入我的頭頂,所以它會充滿錯別字;如果你想讓它在空集合上工作,你需要調整邏輯(應該是顯而易見的)。
Ada 2012的表情功能非常棒!