我正在执行与该站点上已经解决的标志包问题相似的任务(Package bodies and main programs. Simple assignment (Ada)]
但是这次我需要画一个有4折的书皮,如下所示:
Book with folds at the breaking points: 3, 10, 15, 17.
Height = 2, Width = 20,
Title (string(1..100),
Author (string(1..50).
<Title>
<Author>
|--|------|----|-|---|
| | | | | |
| | | | | |
|--|------|----|-|---|
我从exercise_bluebook_main.adb的第25行中发现了很多问题,但是最让我感到困扰的是
exercise_bluebook_main.adb:25:11:预期类型为“ Standard.Integer”,exercise_bluebook_main.adb:25:11:已找到定义为“ Breaking_Array”的类型在exercise_bluebook.ads:7
为什么当为定义的数组输入Im时,为什么期望标准整数?此外,我认为在主过程行15 Im的声明部分会遇到麻烦,因为:= get_line已被“标题”占用。任何人,您将如何解决?
也许代码中的错误更多,我要感谢任何和所有输入,只要它具有建设性!
我的.ads文件
with ada.text_IO; use ada.text_IO;
with ada.integer_text_IO; use ada.integer_text_IO;
package Exercise_BlueBook is
subtype Break_Points is integer range 1..20;
type Breaking_Array is array (1..4) of Break_Points;
type Book_Type is private;
procedure Get (Item: out Book_Type;
Title: in String;
Author: in String;
Width: in Integer;
Height: in Integer;
Break_Points: in Breaking_Array);
procedure Put (Item: in Book_Type);
private
type Book_Type is
record
Title : String(1..100);
Title_L : Integer;
Author : String(1..50);
Author_L : Integer;
Width : Integer;
Height : Integer;
Break_Points : Integer;
end record;
end Exercise_BlueBook;
我的包主体adb文件
with ada.text_IO; use ada.text_IO;
with ada.integer_text_IO; use ada.integer_text_IO;
with Exercise_Bluebook; use Exercise_Bluebook;
package body Exercise_BlueBook is
procedure Get (Item: out Book_Type;
Title: in String;
Author: in String;
Width: in Integer;
Height: in Integer;
Break_Points: in Breaking_Array) is
begin
Item.Title_L := Integer'Min (Item.Title'Length, Title'Length);
Item.Title (1..Item.Title_L) := Title(Title'First .. Item.Title_L);
Item.Author_L := Integer'Min (Item.Author'Length, Author'Length);
Item.Author (1..Item.Author_L) := Author (Author'First .. Item.Author_L);
Item.Width := Width;
Item.Height := Height;
Item.Break_Points := Break_Points;
end Get;
procedure Put (Item: in Book_Type) is
begin
Put_Line(Item.Title(1..Item.Title_L));
Put_Line(Item.Author(1..Item.Author_L));
for H in 1..Item.Height loop
Put("!");
for I in 1..Item.Width loop
Put("-");
if I = Breaking_Array(1) then
Put("!");
elsif I = Breaking_Array(2) then
Put("!");
elsif I = Breaking_Array(3) then
Put("!");
elsif I = Breaking_Array(4) then
Put("!");
end if;
end loop;
Put_Line("!");
end loop;
end Put;
end Exercise_BlueBook;
我的主要步骤
with ada.text_IO; use ada.text_IO;
with ada.integer_text_IO; use ada.integer_text_IO;
with Exercise_Bluebook; use Exercise_Bluebook;
procedure Exercise_BlueBook_Main is
B : Book_Type;
begin
Put("Enter the name of the book: ");
declare
Title : constant String := Get_Line; -- First Get_Line already taken
Author: constant String := Get_Line; -- How do I solve this for "Author"?
Width: Integer;
Height: Integer;
Break_Points : Exercise_BlueBook.Breaking_Array;
begin
Put("Enter the book's width: ");
Get(Width);
Put("Enter the book's height: ");
Get(Height);
Put("Enter the breaking points for the fold: ");
Get(Break_Points); -- Won't read this as an array?
Get(B,
Title => Title,
Author => Author,
Width => Width,
Height => Height,
Break_Points => Break_Points);
end;
New_Line;
Put(B);
end Exercise_BlueBook_Main;
解决方案1
Get
程序包中的Ada.Integer_Text_IO
子程序将只读取一个整数。您可以通过添加循环来扩展它:main.adb
with Ada.Text_IO;
with Ada.Integer_Text_IO;
procedure Main is
package TIO renames Ada.Text_IO;
package IIO renames Ada.Integer_Text_IO;
type Int_Array is array (Natural range <>) of Integer;
---------
-- Get --
---------
function Get (From : String; Max_Elems : Natural) return Int_Array is
Result : Int_Array (1 .. Max_Elems);
Num_Elems : Natural := 0;
Last : Natural := From'First - 1;
begin
while Last + 1 <= From'Last and Num_Elems + 1 <= Max_Elems loop
declare
Value : Integer;
begin
IIO.Get (From (Last + 1 .. From'Last), Value, Last);
Num_Elems := Num_Elems + 1;
Result (Num_Elems) := Value;
end;
end loop;
return Result (1 .. Num_Elems);
end Get;
begin
declare
Arr : Int_Array := Get (TIO.Get_Line, 10);
begin
TIO.New_Line;
TIO.Put_Line("Result:");
for Val of Arr loop
IIO.Put (Val, Width => 3);
TIO.New_Line;
end loop;
end;
exception
when TIO.Data_Error =>
TIO.Put_Line ("Invalid data.");
end Main;
输出
$ ./main
1 2 3
Result:
1
2
3
(无效输入)输出
$ ./main
1 2 x 4 5
Invalid input.
这是替代版本。在这里,您必须使用适当的类型实例化泛型函数。请注意,对数组解决方案2
Breaking_Array
(即1 .. 4
)的约束已移至实例化。main.adb
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Exceptions; use Ada.Exceptions;
procedure Main is
generic
type Num is range <>;
type Arr is array (Integer range <>) of Num;
procedure Get (From : String; Item : out Arr);
---------
-- Get --
---------
procedure Get (From : String; Item : out Arr) is
package Element_IO is
new Ada.Text_IO.Integer_IO (Num);
use Element_IO;
Last : Integer := From'First - 1;
begin
for Elem in Item'Range loop
if Last + 1 > From'Last then
raise Data_Error with "Not enough elements.";
end if;
begin
Element_IO.Get (From (Last + 1 .. From'Last), Item (Elem), Last);
exception
when Data_Error =>
raise Data_Error with "Invalid data.";
end;
end loop;
end Get;
subtype Break_Points is Integer range 1 .. 20;
type Breaking_Array is array (Integer range <>) of Break_Points;
procedure Get_Breaking_Array is
new Get (Break_Points, Breaking_Array);
BA : Breaking_Array (1 .. 4);
begin
Get_Breaking_Array (Get_Line, BA);
New_Line;
Put_Line("Result:");
for BP of BA loop
Put (BP'Image);
New_Line;
end loop;
exception
when DE : Data_Error =>
Put_Line ("Error: " & Exception_Message (DE));
end Main;
(元素太多,仅读取前4个元素。)>输出
$ ./main
1 2 3 4 5 6
Result:
1
2
3
4
(元素太少)。输出
$ ./main
1 2 3
Error: Not enough elements.
(非数字数据)。输出
$ ./main
1 2 x 4
Error: Invalid data.
(元素值超出范围)。输出
$ ./main
1 2 3 100
Error: Invalid data.
Get_Line
调用Title
,然后为Get_Line
调用另一个Author
。使用Get
读取以下数据;起作用的方式是读取字符,跳过空格,直到找到可能是数字一部分的字符,然后再读取更多字符,直到发现某些字符不能成为数字的一部分。