Ada 字符串连接

发布于 2024-10-17 01:13:02 字数 259 浏览 4 评论 0原文

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

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

I have a function that returns a string for a particular item, and I need to call that function numerous times and combine those strings into one. The combined string is bounded. I've made sure to fill it when space characters when it initializes but I keep getting "length check failed" errors. Is there something basic I'm doing wrong here?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

厌味 2024-10-24 01:13:02

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;

或者,您可以使用 Ada.Strings.Fixed Move() 过程将 Unbounded_String 放入目标固定长度字符串中:

Ada.Strings.Fixed.Move(To_String(Temp_Unbounded_String), Combined_String);

在这种情况下,如果源字符串如果“太长”,则默认会引发 Length_Error 异常。 Move() 还有其他参数可以修改这种情况下的行为,请参阅 移动 了解更多详细信息。

Unbounded_String is probably the easiest way to go:

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;

If you then need to have the result placed in your fixed length standard string:

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;

Alternatively, you can use the Ada.Strings.Fixed Move() procedure to bring the Unbounded_String into the target fixed-length string:

Ada.Strings.Fixed.Move(To_String(Temp_Unbounded_String), Combined_String);

In this case, if the source string is "too long", by default a Length_Error exception is raised. There are other parameters to Move() that can modify the behavior in that situation, see the provided link on Move for more detail.

青柠芒果 2024-10-24 01:13:02

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

I know this is an ancient question, but now that Ada 2012 is out I thought I'd share an idiom I've been finding myself using...

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;

Typed off the top of my head, so it'll be full of typos; and if you want it to work on empty collections you'll need to tweak the logic (should be obvious).

Ada 2012's expression functions are awesome!

晚风撩人 2024-10-24 01:13:02

为了分配Combined_String,您必须立即分配完整的正确长度。您无法“构建”字符串并在 Ada 中以这种方式分配它。

在没有看到其余代码的情况下,我认为 Ada.Strings.Unbounded 可能是您应该使用的。

In order to assign Combined_String, you must assign the full correct length at once. You can't "build up" a string and assign it that way in Ada.

Without seeing the rest of your code, I think Ada.Strings.Unbounded is probably what you should be using.

罪歌 2024-10-24 01:13:02

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

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

Ada works best when you can use perfectly-sized arrays and strings. This works wonderfully for 99% of string uses, but causes problems any time you need to progressively build a string from something else.

Given that, I'd really like to know why you need that combined string.

If you really need it like that, there are two good ways I know of to do it. The first is to use "unbounded" (dynamically-sized) strings from Ada.Strings.Unbounded, as Dave and Marc C suggested.

The other is to use a bit of functional programming (in this case, recursion) to create your fixed string. Eg:

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;

I don't know what type you used for Collection, so I'm making some guesses. In particular, I'm assuming its an unconstrained array of fixed strings. If it's not, you will need to replace some of the above code with whatever your container uses to return its bounds, access elements, and perform slicing.

吃→可爱长大的 2024-10-24 01:13:02

来自 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;

*实际上受 Integer'Range、IIRC 限制

From 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;

As you can see, this method builds a string (using Get_Line) of unlimited* length from the file it's reading from. So what you'll need to do, in order to keep what you have is something on the order of:

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;

Assuming that String_Collection is defined as:

 Type String_Collection is Array (Positive Range <>) of Access String;

*Actually limited by Integer'Range, IIRC

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文