我正在研究一个问题,我需要根据输入数字制作一组盒子,其中每个盒子都有唯一的名称。我设法创建了这些框,但由于在名称收集过程中我的名字被覆盖,因此我只设法在所有框上插入一个名字。
这里是代码https://pastebin.com/FBMvvrn4
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure exercise is
N : Integer;
Names : String(1..10);
L : Integer;
procedure Objectcatcha (N: out Integer) is
begin
Put("Enter amount of objects: ");
Get(N);
end Objectcatcha;
procedure Namescatcha (Names: out string; L: out integer) is
begin
for I in 1..N loop
Get_Line(Names, L);
end loop;
end Namescatcha;
procedure SpaceBox(Names: in String; L: in Integer; N : in integer) is
begin
for I in 1..N loop
Put("+-----------+ ");
end loop;
New_Line;
for I in 1..N loop
Put("! ");
Put(Names(1..L));
for J in (L+1)..10 loop
Put(" ");
end loop;
Put("!");
if I = N then
Put("");
else
Put("<>---");
end if;
end loop;
New_Line;
for I in 1..N loop
Put("+-----------+ ");
end loop;
end SpaceBox;
begin
Objectcatcha(N);
Put("Enter the name of the objects: ");
Namescatcha(Names, L);
SpaceBox(Names,L, N);
end exercise;
我已经坐了很多时间,如果有人可以帮助我找到一种分别命名每个框的方法,我将非常高兴。
提前感谢!
您可以在(而且您可以在这里)声明一个确切大小的变量来保存您使用的名称。可以通过将其声明为不确定数组并使用正确的名称对其进行初始化来完成此操作。
所以您的主程序可能是:
Objectcatcha(N);
For I in 1 to N loop
Put("Enter the name of the next object: ");
Declare
Name : String := Namescatcha;
Begin
SpaceBox(Name, Name'Length, N);
End;
End loop;
Namescatcha现在是一个仅返回正确大小的字符串的函数:
function Namescatcha return String is
begin
return Getline;
end Namescatcha;
而且您可能应该重写不带L的空格键(您始终可以使用Name'Length来查看Name的长度)
Brian Drummond已经介绍了如何获取可变长度名称以及使用它们的一些方法。为了解决您的一个名称覆盖所有名称的问题,您必须考虑使用一个名称变量来保存所有名称,因此有意义的是,一个名称将覆盖其他名称。要将多个名称存储在一起,请考虑使用Indefinite_Vector来保存它们。在您的Objectcatcha过程中,您可以获得容量,因此可以使用它来设置矢量的大小
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Indefinite_Vectors; use Ada.Containers;
-- Other stuff
package Name_Vectors is new Indefinite_Vectors
(Index_Type => Positive,
Element_Type => String);
Names : Name_Vectors.Vector;
package Count_Type_IO is new Integer_IO(Count_Type);
procedure Objectcatcha is
Number : Count_Type;
Last : Positive; -- Placeholder for Get call
begin
Put("Enter amount of objects: ");
Count_Type_IO.Get
(From => Get_Line,
Item => Number,
Last => Last);
Names.Reserve_Capacity(Number);
end Objectcatcha;
procedure Namescatcha is
begin
for Index in 1..Names.Capacity loop
Names.Append(Get_Line);
end loop;
end Namescatcha;
您将需要调整SpaceBox过程以使用矢量而不是名称,或一次只使用一个名称(您的选择)。
一些注意事项:1.我将您的Get调用更改为Get_Line以获取名称的数量,您可以根据需要将其更改回去。2.当我将名称存储在矢量中时,存储的最后一个字符可能是“换行”字符,因此您可能必须将其删除。这很容易做到。只需使用名称的所有字符(最后一个除外)即可。例如:
declare
Name : String := Names(Index);
begin
Put(Name(1..Name'Length-1));
end;
由于您的程序似乎不是对性能至关重要的应用程序,因此我将使用可变大小的字符串来避免存储N个不同的字符串长度。在普通的Ada中,可变大小的字符串称为Unbounded_String
。在这里,您使用开放源代码程序包(hac_pack:spec,body)进行练习,该程序包可以方便地处理可变大小字符串。
with HAC_Pack; use HAC_Pack;
procedure Names_in_Boxes is
Max : constant := 100;
type Names_Type is array (1 .. Max) of VString;
procedure Objectcatcha (N: out Integer) is
begin
Put("Enter amount of objects: ");
Get(N);
Skip_Line;
end Objectcatcha;
procedure Namescatcha (Names: out Names_Type; N : in Integer) is
begin
for I in 1..N loop
Put(+"Object " & I & ": ");
Get_Line(Names (I));
end loop;
end Namescatcha;
procedure SpaceBox(Names: in Names_Type; N : in Integer) is
begin
Put_Line (N * (+"+-----------+ "));
for I in 1..N loop
Put("! " & Names(I) & (10 - Length(Names(I))) * ' ' & "!");
if I = N then
Put("");
else
Put("<>---");
end if;
end loop;
New_Line;
Put_Line (N * (+"+-----------+ "));
end SpaceBox;
-- "Global" variables, unknown to
-- Objectcatcha, Namescatcha, SpaceBox:
N : Integer;
Names : Names_Type;
begin
Objectcatcha(N);
Put_Line("Enter the name of the objects: ");
Namescatcha(Names, N);
SpaceBox(Names, N);
end Names_in_Boxes;
感谢Zerte,Jere和Brian的例子,非常感谢。不幸的是,我不能使用第三方软件包来排除Zertes解决方案,对于Jere,我很抱歉,但是Im只是一个简单的代码猴子,具有非常浅的ADA知识,您的示例对我来说太复杂了。即使我得到了正确的代码并且可以正常工作,我仍然不会学习它,因为它与我学校所教的内容相差太大。就像没有输入/输出参数的程序一样。也许我误会了,它还不错,但是乍一看,对于我的ADA级别来说似乎太复杂了。