2011-02-14 109 views
3

我有一个函数返回一个特定项目的字符串,我需要多次调用该函数并将这些字符串合并为一个。组合的字符串是有界的。我已经确定在空格字符初始化时填充它,但我一直收到“长度检查失败”错误。有没有什么基本的我在这里做错了?Ada字符串串联

FOR I IN 1..Collection.Size LOOP 
    Combined_String := combined_string & Tostring(Collection.Book(I)); 
END LOOP; 

回答

3

为了分配Combined_String,您必须一次性指定完全正确的长度。你不能“建立”一个字符串并在Ada中这样分配。

没有看到你的代码的其余部分,我认为Ada.Strings.Unbounded可能是你应该使用的。

5

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上提供的链接。

1

当您可以使用完美大小的数组和字符串时,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; 

我不知道你使用什么类型的集合,所以我做了一些猜测。特别是,我假设它是一个不受约束的固定字符串数组。如果不是,则需要将上面的一些代码替换为您的容器用来返回其边界,访问元素和执行切片的任何内容。

1

AdaPower.com

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

2

我知道这是一个古老的问题,但现在,阿达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的表情功能非常棒!