ADA 95教程 示例程序3

使用动态字符串

Example program ------> e_c16_p4.ada

 -- Chapter 16 - Program 4
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_text_IO; use Ada.Integer_Text_IO;
with DynStrng; use DynStrng;

procedure TryStrng is

   Try_This : STRING(1..13);
   Name     : DYNAMIC_STRING(0..15);
   Stuff    : DYNAMIC_STRING(0..35);
   Result   : BOOLEAN;
   Neat     : constant STRING := "XYZ";
   Good3    : STRING(1..3);
   Good4    : STRING(1..4);
   Column   : INTEGER;

begin

   Name(0) := CHARACTER'VAL(3);
   Stuff(0) := CHARACTER'VAL(7);

   Put(Size_Of(Name));
   Put(Size_Of(Stuff));
   Put(Length(Name));
   Put(Length(Stuff));
   New_Line;

   Try_This := "ABCDEFGHIJKL$";
   Copy(Try_This,Stuff,Result);
   Put(Size_Of(Stuff));
   Put(Length(Stuff));
   Put(Stuff); Put(Stuff);
   New_Line(2);

   Copy(Stuff,Name,Result);
   Put(Name); Put(Name); Put(Name); New_Line;

   Concat(Name,Name,Stuff,Result);
   Put(Stuff); New_Line;

   Delete(Stuff,5,3,Result);
   Put(Stuff); New_Line;
   Delete(Stuff,6,3,Result);
   Put(Stuff); New_Line;
   Delete(Stuff,6,3,Result);
   Put(Stuff); New_Line;
   Delete(Stuff,6,3,Result);
   Put(Stuff); New_Line;
   Delete(Stuff,6,3,Result);
   Put(Stuff); New_Line;
   Delete(Stuff,6,3,Result);
   Put(Stuff); New_Line;
   Delete(Stuff,6,3,Result);
   Put(Stuff); New_Line;
   Delete(Stuff,6,3,Result);
   Put(Stuff); New_Line(2);

   Try_This := "1234567890123";
   Copy(Try_This,Stuff,Result);
   Copy(Neat,Name,Result);
   Put(Stuff); Put(Name); New_Line;

   Insert(Stuff,Name,5,Result);
   Put(Stuff); New_Line;
   Insert(Stuff,Name,50,Result);
   Put(Stuff); New_Line;
   Insert(Stuff,Name,2,Result);
   Put(Stuff); New_Line;
   Insert(Stuff,Name,24,Result);
   Put(Stuff); New_Line;
   Insert(Stuff,Name,5,Result);
   Put(Stuff); New_Line;
   Insert(Stuff,Name,5,Result);
   Put(Stuff); New_Line;
   Insert(Stuff,Name,5,Result);
   Put(Stuff); New_Line;
   Insert(Stuff,Name,5,Result);
   Put(Stuff); New_Line(2);

   Good3 := "123";
   Try_This := "1234567890123";
   Copy(Try_This,Stuff,Result);
   Copy(Good3,Name,Result);
   Pos(Stuff,Name,1,Column,Result);
   Ada.Text_IO.Put("Found in column number"); Put(Column); New_Line;
   Pos(Stuff,Name,2,Column,Result);
   Ada.Text_IO.Put("Found in column number"); Put(Column); New_Line;
   Pos(Stuff,Name,7,Column,Result);
   Ada.Text_IO.Put("Found in column number"); Put(Column); New_Line;
   Pos(Stuff,Name,12,Column,Result);
   Ada.Text_IO.Put("Found in column number"); Put(Column); New_Line;
   Pos(Stuff,Name,18,Column,Result);
   Ada.Text_IO.Put("Found in column number"); Put(Column); New_Line;
   Pos(Stuff,Name,50,Column,Result);
   Ada.Text_IO.Put("Found in column number"); Put(Column); New_Line;

end TryStrng;

 

示例程序e_c16_p4.ada旨在通过定义字符串、插入字符或字符串、删除部分字符串和显示结果,以各种方式使用动态字符串包。这个程序是用来测试DynStrng包的,所以它做了很多愚蠢的事情。在这个实用的程序中没有什么新的或创新的东西,所以你只能自己去理解、编译和执行它。

e_c16_p3.ada有一个问题

DynStrng包的工作方式与TryStrng包中使用的方式一样,但是当它用于将字符串常量复制到动态字符串中时,就会出现问题。这个问题是由于在DynStrng规范的第60行和第63行重载了名称副本造成的,最好用一个例子来说明。考虑下面的Ada代码行;

  Copy("Line of text.", Stuff, Result);

在本例中,编译器发现STRING常量可能是string类型或DYNAMIC_STRING类型,并且不知道要使用哪个重载,因此它给出了一个编译错误,表示无法解析该类型。使用这个包的方法是通过限定字符串常量来告诉编译器要使用哪一个,如这行代码所示。

   Copy(STRING'("Line of text."), Stuff, Result);

这将完全解决歧义,然后程序将正确编译和执行。您应该在测试程序中包含这两行代码,以亲眼看看这是否解决了歧义。

 

现在来解决问题

有一个很好的解决方案,它将使这个动态字符串包灵活和有用,但它需要使用一个判别记录,我们还没有在本教程中研究过。在本教程的第2部分中,我们将重新讨论这个动态字符串包,并为您的信息和使用提供一个更灵活的包。

 

DYNAMIC_STRING包是一个很好的包,您可以学习如何开发包,以及典型包如何工作。然而,它已经被两个新的软件包取代,可用于任何Ada 95程序。名为Ada.Strings.Unbounded,和Ada.Strings.Unbounded是Ada 95标准库的一部分,可供您使用。你应该彻底了解他们的能力和局限性,因为它们可以节省你很多时间。

 

你几天多大了?

Example program ------> e_c16_p5.ada

 -- Chapter 16 - Program 5
-- This program will calculate the number of days old you are.
-- It is a rather dumb program, but illustrates some interesting
-- programming techniques.  It checks all input to see that they
-- are in the correct range before continuing.  Since the number
-- of days can easily exceed the limits of type INTEGER, and we
-- cannot count on LONG_INTEGER being available, a fixed point
-- variable is used for the total number of days since Jan 1, 1880.
-- This program also passes a record to a procedure, where it is
-- modified and returned.

with Ada.Text_IO, Ada.Integer_Text_IO;
use ADa.Text_IO, Ada.Integer_Text_IO;

procedure Age is

   LOW_YEAR    : constant := 1880;
   MAX         : constant := 365.0 * (2100 - LOW_YEAR);
   type AGES is delta 1.0 range -MAX..MAX;
   Present_Age : AGES;

   package Fix_IO is new Ada.Text_IO.Fixed_IO(AGES);
   use Fix_IO;

   type DATE is record
      Month : INTEGER range 1..12;
      Day   : INTEGER range 1..31;
      Year  : INTEGER range LOW_YEAR..2100;
      Days  : AGES;
   end record;

   Today       : DATE;
   Birth_Day   : DATE;

   procedure Get_Date(Date_To_Get : in out DATE) is
   Temp : INTEGER;
   begin
      Put(" month --> ");
      loop
         Get(Temp);
         if Temp in 1..12 then
            Date_To_Get.Month := Temp;
            exit;                       -- month OK
         else
            Put_Line(" Month must be in the range of 1 to 12");
            Put("                    ");
            Put(" month --> ");
         end if;
      end loop;

      Put("                    ");
      Put(" day ----> ");
      loop
         Get(Temp);
         if Temp in 1..31 then
            Date_To_Get.Day := Temp;
            exit;                       -- day OK
         else
            Put_Line(" Day must be in the range of 1 to 31");
            Put("                    ");
            Put(" day ----> ");
         end if;
      end loop;

      Put("                    ");
      Put(" year ---> ");
      loop
         Get(Temp);
         if Temp in LOW_YEAR..2100 then
            Date_To_Get.Year := Temp;
            exit;                       -- year OK
         else
            Put_Line(" Year must be in the range of 1880 to 2100");
            Put("                    ");
            Put(" year ---> ");
         end if;
      end loop;
      Date_To_Get.Days := 365 * AGES(Date_To_Get.Year - LOW_YEAR)
                  + AGES(31 * Date_To_Get.Month + Date_To_Get.Day);

   end Get_Date;

begin
   Put("Enter Today's date; ");
   Get_Date(Today);
   New_Line;

   Put("Enter your birthday;");
   Get_Date(Birth_Day);
   New_Line(2);

   Present_Age := Today.Days - Birth_Day.Days;
   if Present_Age < 0.0 then
      Put("You will be born in ");
      Present_Age := abs(Present_Age);
      Put(Present_Age, 6, 0, 0);
      Put_Line(" days.");
    elsif Present_Age = 0.0 then
      Put_Line("Happy birthday, you were just born today.");
    else
      Put("You are now ");
      Put(Present_Age, 6, 0, 0);
      Put_Line(" days old.");
   end if;

end Age;

这个名为e_uc16_up5.ada的示例程序是一个愚蠢的小程序,但旨在说明如何有效地使用键盘输入程序。这个程序会要求你今天的日期,你的生日,然后计算你的年龄,以天为单位。闰年,甚至连31天以外的几个月都没有规定。它旨在说明如何组合一个互动程序,以某种方式可能有用。

再次,由于我们还没有研究Ada的高级主题,所以我们有有限的结构要使用。本教程第2部分末尾的示例程序重复此程序,但使用预定义的Ada包日历获取今天的日期,而不是要求用户提供它。高级主题将为您使用Ada增加灵活性。编译并运行此程序,以了解如何编写交互式程序。

 

编程练习

1.向 e_c16_p1ada添加一个附加函数,以返回一个值,该值指示可以将更多字符推到堆栈上。(Solution)

2.使用e_c16_p2.ada中的新功能向监视器输出一条消息,指示 Fill_The_Stack 过程结束时堆栈上剩余的空间量。(Solution)

3.一个主要的编程任务-学习Ada的最好方法是使用它,因此给出了以下编程建议。在研究了e_C16_P3.ada包后,将其放在一边,并试图从头复制。您将发现,您将使用本教程第1部分中所涵盖的几乎所有主题,如果您完全陷入困境,您将获得该包的提供版本,以帮助您克服困难。您的目标应该是复制提供的包,以便现有的名为e_C16_P4.ada的程序可以使用您的新版本。如果您发现e_C16_P3.ada太大,无法进行第一步,您可能希望在跳入动态字符串工作之前以相同的方式复制e_C16_P1.ada。

 

---------------------------------------------------------------------------------------------------------------------------

原英文版出处:https://perso.telecom-paristech.fr/pautet/Ada95/a95list.htm

翻译(百度):博客园  一个默默的 *** 的人

 

posted @ 2021-04-08 21:26  yangjianfeng  阅读(74)  评论(0编辑  收藏  举报