ADA 95教程 输入输出

ADA对I/O不太重视

Ada最初是作为一种嵌入式实时系统的语言而设计的,而不是作为一种面向业务的语言,因此数据的输入和输出是该语言中优先级较低的部分。如果您知道Ada语言本身中没有可供使用的输入或输出指令,您可能会感到惊讶,这个问题将留给编译器编写者来解决。然而,Ada的设计人员意识到,如果将输入和输出的整个主题留给各个编译器编写者,那么用户在尝试使用非标准的输入和输出方法时就会陷入混乱。他们通过定义一个标准的外部库来实现巨大的远见,该库用于输入和输出所有通过验证套件的Ada编译器都必须提供的数据。

即使这些库已经定义,但它们的操作细节并没有被精确定义,因此您的编译器仍有可能不会以与这里给出的描述完全相同的方式运行。您必须检查与编译器一起打包的文档,以发现输入和输出操作的确切细节。不过,你可以放心,区别只会在最小的细节上。

 

包实例化

在我们研究一些文本输出过程之前,我们需要先了解另一个主题。我们在前几章提到了包实例化,我们已经到了应该在某种程度上定义它的地步。Ada提供了编写泛型包的能力,这些泛型包可以在不重写代码的情况下为几种不同的类型提供相同的功能。泛型包没有与之相关联的类型,因此我们告诉系统,我们希望它通过用特定类型实例化泛型包的副本来处理特定类型。例如,如果我们有4种不同的类型需要处理,我们为这四种类型中的每一种实例化一个副本,然后我们可以对每一种类型的变量执行相同的操作。实例化是一种奇特的方式,可以说我们创建了泛型包的“实例”。这些都将在本Ada教程的第2部分中详细介绍。

ada95环境为我们提供了一些预先实例化的通用包。例如,通用包的副本 Ada.Text_IO.Integer_IO是针对Integer类型预先实例化的,并命名为Ada.Integer_Text_IO我们在本教程中使用的。同样地Ada.Float_Text_IO是名为Ada.Text_IO.Float_IO用于类型Float。现在我们有另一个问题,因为我们需要定义这一段中提到的通用包来自何处。最好的答案是,它们是我们的编译器附带的,在本教程第2部分学习泛型包之前,我们只需按照图示使用它们。

我们的编译器编写人员可能还为我们提供了其他预实例化包。每个Ada编译器都需要提供INTEGER和FLOAT类型,但是可以提供其他类型。例如,可以提供LONG_FLOATSHORT_FLOAT类型,每个类型都有自己的特性,每个类型都有自己的 input/output 包,名为Ada.Long_Float_Text_IO或者Ada.Short_Float_Text_IO. 其他类型可以是SHORT_INTEGERSHORT_SHORT_INTEGER或INTEGER的其他变体,以及包Ada.Short_Integer_Text_IO or Ada.Short_Short_Integer_Text_IO.您应该花一些时间研究编译器的功能和限制,看看哪些类型可供您使用。

您会注意到,这些包中有许多是以Ada开头的。钉在全名的前面。ada95包括定义和使用层次库的能力,许多ada95包都声明为Ada库的一部分。我们稍后将更详细地介绍这些库,以及以这种方式打包它们的原因。

在简要介绍之后,让我们看看一些文本输出过程。

 

格式化输出数据

Example program ------> e_c14_p1.ada

     -- Chapter 14 - Program 1
with Ada.Text_IO;
use Ada.Text_IO;

procedure Formats is

   type MY_FIXED is delta 0.01 range 20.0..42.0;
   type DAY is (MON, TUE, WED, THU, FRI, SAT, SUN);
   type MY_INTEGER is range -13..323;

   X_Value : FLOAT := 3.14;
   Index   : INTEGER := 27;
   Count   : MY_INTEGER := -7;
   What    : BOOLEAN := TRUE;
   Who     : BOOLEAN := FALSE;
   Size    : MY_FIXED := 24.33;
   Today   : DAY := TUE;

   package Int_IO is new Ada.Text_IO.Integer_IO(INTEGER);
   use Int_IO;
   package Flt_IO is new Ada.Text_IO.Float_IO(FLOAT);
   use Flt_IO;
   package Enum_IO is new Ada.Text_IO.Enumeration_IO(BOOLEAN);
   use Enum_IO;

   package Fix_IO is new Ada.Text_IO.Fixed_IO(MY_FIXED);
   use Fix_IO;
   package Day_IO is new Ada.Text_IO.Enumeration_IO(DAY);
   use Day_IO;
   package New_Int_IO is new Ada.Text_IO.Integer_IO(MY_INTEGER);
   use New_Int_IO;

begin
                                       -- INTEGER outputs
   Put("Index is --->"); Put(Index);   Put("<---"); New_Line;
   Put("Index is --->"); Put(Index,3); Put("<---"); New_Line;
   Put("Index is --->"); Put(Index,8); Put("<---"); New_Line(2);
   Put("Count is --->"); Put(Count);   Put("<---"); New_Line;
   Put("Count is --->"); Put(Count,3); Put("<---"); New_Line;
   Put("Count is --->"); Put(Count,8); Put("<---"); New_Line(2);

                                       -- FLOAT outputs
   Put("Put(X_Value) -------->"); Put(X_Value);        New_Line;
   Put("Put(X_Value,5) ------>"); Put(X_Value,5);      New_Line;
   Put("Put(X_Value,5,5) ---->"); Put(X_Value,5,5);    New_Line;
   Put("Put(X_Value,5,5,0) -->"); Put(X_Value,5,5,0);  New_Line(2);

                                       -- MY_FIXED outputs
   Put("Put(Size) -------->"); Put(Size);        New_Line;
   Put("Put(Size,5) ------>"); Put(Size,5);      New_Line;
   Put("Put(Size,5,5) ---->"); Put(Size,5,5);    New_Line;
   Put("Put(Size,5,5,0) -->"); Put(Size,5,5,0);  New_Line(2);

                                       -- BOOLEAN outputs
   Put("What is ---->"); Put(What);   Put("<---"); New_Line;
   Put("Who is ----->"); Put(Who);    Put("<---"); New_Line;
   Put("What is ---->"); Put(What,7); Put("<---"); New_Line;
   Put("Who is ----->"); Put(Who,8);  Put("<---"); New_Line;
   Put("TRUE is ---->"); Put(TRUE);   Put("<---"); New_Line;
   Put("FALSE is --->"); Put(FALSE);  Put("<---"); New_Line(2);

                                       -- Enumeration outputs
   Put("Today is --->"); Put(Today);   Put("<---"); New_Line;
   Put("Today is --->"); Put(Today,6); Put("<---"); New_Line;
   Put("Today is --->"); Put(Today,7); Put("<---"); New_Line;
   Put("WED is ----->"); Put(WED);     Put("<---"); New_Line;
   Put("WED is ----->"); Put(WED,5);   Put("<---"); New_Line(2);

end Formats;




-- Result of execution

-- Index is --->    27<---
-- Index is ---> 27<---
-- Index is --->      27<---
--
-- Count is --->    -7<---
-- Count is ---> -7<---
-- Count is --->      -7<---
--
-- Put(X_Value) --------> 3.14000E+00
-- Put(X_Value,5) ------>    3.14000E+00
-- Put(X_Value,5,5) ---->    3.14000E+00
-- Put(X_Value,5,5,0) -->    3.14000
--
-- Put(Size) --------> 24.33
-- Put(Size,5) ------>   24.33
-- Put(Size,5,5) ---->   24.33008
-- Put(Size,5,5,0) -->   24.33008
--
-- What is ---->TRUE<---
-- Who is ----->FALSE<---
-- What is ---->TRUE   <---
-- Who is ----->FALSE   <---
-- TRUE is ---->TRUE<---
-- FALSE is --->FALSE<---
--
-- Today is --->TUE<---
-- Today is --->TUE   <---
-- Today is --->TUE    <---
-- WED is ----->WED<---
-- WED is ----->WED  <---

 

如果您检查程序e_c14_p1.ada,您会发现它除了说明将格式化数据输出到监视器的各种方法外,几乎没有其他作用。声明了几个类型和变量,然后对Ada.Text_IO文件声明与程序中使用的六种类型一起使用。事实上,这里对你们来说没有什么新的,因为我们之前已经讨论过所有这些陈述,但是这里包括它们是为了在一个地方展示所有这些陈述的一个例子。

在这一点上应该发表一些意见。请注意 Ada.Text_IO文件第19行到第31行中给出的包。这些是必要的,以便输出我们在这个程序中使用的各种类型。必须在声明各种类型之后声明包实例化。在输出MY_INTEGER类型变量之前,可以通过将其类型转换为INTEGER 类型来消除其中一个实例化,但这样做只是为了说明。当我们实例化一个包时,实际上我们使用的是一个通用包的副本,这将是本教程第2部分详细研究的主题。

在研究并理解了程序之后,编译并运行它,以获得一组详细的格式化输出示例。由于编译器指定的默认值不同,编译器的浮点输出和固定输出可能与执行结果中给出的输出略有不同。

 

格式化输出到文件

Example program ------> e_c14_p2.ada  

-- Chapter 14 - Program 2
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;

procedure EasyOut is

   Turkey : FILE_TYPE;

begin
                             -- First we create the file
   Create(Turkey, Out_File, "TEST.TXT");
                             -- Then we write to it
   Put_Line(Turkey, "This is a test of turkey");
   Put(Turkey, "and it should work well.");
   New_Line(Turkey, 2);
   Put_Line("Half of the turkey test");

   Set_Output(Turkey);       -- Make Turkey the default output
      Put_Line("This is another test of turkey");
      Put("and it should work well.");
      New_Line(2);
      Put_Line(Standard_Output, "Half of the turkey test");
   Set_Output(Standard_Output); -- Return to the Standard default

   Put_Line("Back to the standard default output.");
   Close(Turkey);

end EasyOut;




-- Result of execution

-- (Output to the monitor follows)
--
-- Half of the turkey test
-- Half of the turkey test
-- Back to the standard default output

-- (Output to the file TEST.TXT)
--
-- This is a test of turkey
-- and it should work well.
--
-- This is another test of turkey
-- and it should work well.

 

名为e_c14_p2.ada的示例文件包含如何以非常简单的方式使用文件的示例。由于没有所有操作系统都使用的命名文件的标准方法,因此我们不能依赖于在任何系统上使用Ada的规则,因此我们需要两个文件名才能写入或读取文件。我们需要一个内部名称,它将被我们的程序用来引用文件,并遵循Ada定义的命名规则。我们还需要一个外部名称,它将被操作系统用来引用文件,并且它的名称遵循操作系统指定的规则。除了拥有这两个名称之外,我们还需要一种方法将名称相互关联,并告诉系统我们希望使用这样命名的文件。所有这些都是通过Create过程完成的,如本程序第11行所示。

变量Turkey是我们在第7行中声明的内部文件名,它的类型为File_Type,是由包导出的类型Ada.Text_IO文件就为了这个目的。The "with Ada.Text_IO;";”第2行中的语句使类型File_Type在此程序中可用。最后一个参数是字符串常量(如本例所示)或字符串变量,它给出了要创建和写入的文件的外部名称。请注意,如果您有一个名为TEST.TXT在默认目录中,执行此程序时它将被删除,因为此语句将删除它。此过程调用中的第二个参数,如果要从文件中读取,则In_File中;如果要写入,则Out_File。不存在使用文本I/O的模式,在这种模式下,您可以对同一个文件进行读写操作。在本例中,我们希望写入该文件,因此我们使用mode Out_File并创建该文件。

 

正在写入文件

第13行看起来很熟悉,因为它是我们的老朋友在我们想要输出的文本之前加上一个额外参数。由于Turkey 是FILE_TYPE类型,系统非常聪明,可以知道这个字符串将输出到具有Turkey 内部名称的文件,以及外部名称为TEST.TXT,因此字符串将与 "carriage return/line feed"一起指向那里。下一行也将被引导到那里,第15行中要求的2条 New_Lines 也将被引导到那里。第16行没有Turkey 的文件名作为参数,因此它将以与本教程中所有教程相同的方式定向到默认输出设备监视器。

 

重定向输出

第18行包含对过程 Set_Output 的调用,该调用将使作为实际参数的文件名成为默认文件名。只要有效,没有文件名的任何输出都将被指向具有内部文件名Turkey的文件。为了将一些数据输出到监视器,它仍然可以完成,但是必须将其内部文件名作为参数指向监视器,内部文件名为 Standard_Output。第19行至第22行中给出的发言组与第13行至第16行所作的基本相同。默认值返回到第23行的标准输出设备,程序正常完成。

 

关闭文件

第26行中给出的简单语句用于在完成文件时关闭文件。系统只需要给定文件的内部名称,因为它知道相应的外部文件名。在这样简单的程序中,如果文件关闭不成功,不会造成任何伤害,因为操作系统会自动关闭文件,但在大型程序中,如果不再需要关闭文件,最好关闭文件。一次打开多少文件可能有上限,在不需要的文件上浪费文件分配是没有意义的。

请确保编译并运行此程序,然后检查默认目录以查看文件名TEST.TXT包含预期文本的文件中。

 

一次打开多个文件

Example program ------> e_c14_p3.ada

 -- Chapter 14 - Program 3
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;

procedure MultOut is

   Numbers, Some_Text, More_Text : FILE_TYPE;
   Index : INTEGER;

begin

   Create(Numbers, Out_File, "INTDATA.TXT");
   Create(Some_Text, Out_File, "TEST.TXT");
   Create(More_Text, Out_File, "CHARACTS.TXT");

   for Count in 3..5 loop
      Put(Some_Text, "This line goes to the TEST.TXT file.");
      Put(More_Text, "This line goes to the CHARACTS.TXT file.");
      for Count2 in 12..16 loop
         Put(Numbers, Count + Count2);
      end loop;
      New_Line(More_Text);
      New_Line(Numbers, 2);
      New_Line(Some_Text);
   end loop;

   Put_Line("INTDATA.TXT, TEST.TXT, and CHARACTS.TXT are ready.");

   Close(Numbers);
   Close(Some_Text);
   Close(More_Text);

end MultOut;




-- Results of execution


-- (Output to the monitor)
--
-- INTDATA.TXT, TEST.TXT, and CHARACTS.TXT are ready.


-- (Output to the file named INTDATA.TXT)
--
--     15    16    17    18    19
--
--     16    17    18    19    20
--
--     17    18    19    20    21
--


-- (Output to the file named TEST.TXT)
--
-- This line goes to the TEST.TXT file.
-- This line goes to the TEST.TXT file.
-- This line goes to the TEST.TXT file.


-- Output to the file named CHARACTS.TXT)
--
-- This line goes to the CHARACTS.TXT file.
-- This line goes to the CHARACTS.TXT file.
-- This line goes to the CHARACTS.TXT file.

 

检查文件e_c14_p3.ada以获得一个示例程序,在该程序中,我们打开并使用3个不同的文件和监视器。这三个内部文件名在第7行中声明,所有这三个文件名都在输出模式下以三个不同的外部名称打开,如第12、13和14行所示。

我们在第16行到第25行执行循环,在循环中,我们向三个文件写入无意义的数据,向第27行的显示器输出一个测试字符串,最后关闭所有三个文件。请注意,我们可以将其中一个文件定义为默认文件并在不使用文件名的情况下写入该文件,然后在第27行中使用该文件名作为标准输出,从而获得相同的结果。

这个程序相当简单,所以在您理解它之后,编译并运行它。成功运行后,检查默认目录以查看这三个文件是否存在并包含预期的结果。不要删除生成的文件,因为我们将在接下来的几个程序中使用它们作为示例输入文件。

 

从文件输入字符

Example program ------> e_c14_p4.ada

  -- Chapter 14 - Program 4
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;

procedure CharIn is

   My_File  : FILE_TYPE;
   One_Char : CHARACTER;

begin

   open(My_File, In_File, "CHARACTS.TXT");

   loop       -- Read one character at a time and display it
      exit when End_Of_File(My_File);
      Get(My_File, One_Char);
      Put(One_Char);
   end loop;
   New_Line(2);

   Reset(My_File);  -- Reset and start over with the same file

   loop       -- Read and display but search for End of lines
      exit when End_Of_File(My_File);
      Get(My_File, One_Char);
      if End_Of_Line(My_File) then
         Put("<--- End of line found");
         New_Line;
      else
         Put(One_Char);
      end if;
   end loop;
   New_Line;

   Reset(My_File);  -- Reset and start over the third time

              -- Read and display but search for End of lines
   loop       -- using a look ahead method
      exit when End_Of_File(My_File);
      Get(My_File, One_Char);
      Put(One_Char);
      if End_Of_Line(My_File) then
         Put("<--- End of line found");
         New_Line;
      end if;
   end loop;

   Close(My_File);

end CharIn;




-- Result of execution

-- (Note; the first line is a full 80 columns wide.)
-- This line goes to the CHARACTS.TXT file.This line goes to...
-- This line goes to the CHARACTS.TXT file.
--
-- This line goes to the CHARACTS.TXT file<--- End of line found
-- This line goes to the CHARACTS.TXT file<--- End of line found
-- This line goes to the CHARACTS.TXT file<--- End of line found
--
-- This line goes to the CHARACTS.TXT file.<--- End of line found
-- This line goes to the CHARACTS.TXT file.<--- End of line found
-- This line goes to the CHARACTS.TXT file.<--- End of line found

 

检查文件e_c14_p4.ada以获取如何从文件中读取CHARACTER 类型数据的示例。在本例中,文件名My_File被声明为 FILE_TYPE类型变量,然后用于打开CHARACTS.TXT用于读取,因为使用了In_File模式。在这种情况下,文件必须存在,否则将引发异常。文件指针由Open过程设置为文件的开头,因此我们将在第一次读取文件时读取文件中的第一个字符。

第14行到第18行中的循环使我们从文件中读取一个字符,并在每次通过循环时将其显示在监视器上。当要读取的下一个字符是特定实现的文件结尾字符时,函数End_Of_File返回TRUE。我们不需要知道文件结尾字符是什么,而是由编译器编写器来找出它是什么,并在系统找到它时返回值TRUE。因此,该程序会将整个文件显示在监视器上,但与预期略有偏差。由于Ada的定义方式,Get过程只会忽略行尾字符,因为它们没有读入,所以也不能输出到监视器。最终的结果是所有字符都输出在一个长字符串中,没有换行符。稍后编译和运行程序时将看到这一点。

我们将在这个程序中继续我们的研究,并看到一个更好的方法来读取和显示数据。

 

重置程序

第21行中的重置过程重置名为参数的文件,这意味着文件指针再次移动到第一个字符。该文件已准备好下次读取。第23行到第32行中的循环与前一个循环相同,只是添加了另一个新函数。当找到一行的结尾时,函数End_Of_Line返回一个TRUE,程序在第27行显示特殊的小消息。除了消息之外,还将调用 New_Line过程来提供丢失的行尾。

不幸的是,我们仍然有一个问题,因为 End_Of_Line实际上是一个前瞻函数,当缓冲区中的下一个字符是行的结尾字符时,它就变成了真的。当程序被执行时,我们发现它不会输出循环中每一行的最后一个字符,因为我们从未在if语句中为该字符执行else子句。当程序执行时,您会注意到句子末尾的句点没有显示。本程序的下一个循环将说明如何正确地输入和输出数据,同时考虑到Ada的所有特性。

如果您还记得的话,我们在本课开始时说过,Ada中的输入和输出编程充其量只是一种折衷。别担心,你很快就能输入或输出你想要的任何东西。

 

正确的字符输入/输出循环

第35行再次重置文件,第38到46行的第三个循环读取并在监视器上显示文件。这一次,当我们遍历循环时,我们意识到行尾是在读取输入文件中的一个字符,而不是刚刚读取的字符,因此我们相应地调整程序。我们输出字符,然后检查行尾,如果检测到行尾,则调用New_Line 过程。当您运行它时,您将看到行上的最后一个字符将按需要显示。

需要指出的是,文件的结尾是另一个lookahead函数,必须在输出读入的最后一个字符后进行测试。这个循环就是这样做的,因为文件的结尾是在字符输出之后操作的。

一定要编译并运行这个程序。编辑输入文件会很有趣,CHARACTS.TXT,添加几个字符,然后重新运行程序以查看它如何处理新数据。

 

字符串输入和输出

Example program ------> e_c14_p5.ada

-- Chapter 14 - Program 5
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;

procedure StringIn is

   My_File   : FILE_TYPE;
   My_String : STRING(1..10);

begin

   Open(My_File, In_File, "CHARACTS.TXT");

   loop       -- Read one string at a time and display it
      exit when End_Of_File(My_File);
      Get(My_File, My_String);
      Put(My_String);
   end loop;
   New_Line(2);

   Reset(My_File);  -- Reset and start over with the same file

   loop       -- Read and display but search for End of lines
      exit when End_Of_File(My_File);
      Get(My_File, My_String);
      Put(My_String);
      if End_Of_Line(My_File) then
         Put_Line("<--- End of line found");
      else
         Put_Line("<--- 10 characters");
      end if;
   end loop;
   New_Line;

   Close(My_File);

end StringIn;




-- Result of execution

-- (Note; The first line is a full 80 columns wide.)
-- This line goes to the CHARACTS.TXT file.This line goes to ...
-- This line goes to the CHARACTS.TXT file.
--
-- This line <--- 10 characters
-- goes to th<--- 10 characters
-- e CHARACTS<--- 10 characters
-- .TXT file.<--- End of line found
-- This line <--- 10 characters
-- goes to th<--- 10 characters
-- e CHARACTS<--- 10 characters
-- .TXT file.<--- End of line found
-- This line <--- 10 characters
-- goes to th<--- 10 characters
-- e CHARACTS<--- 10 characters
-- .TXT file.<--- End of line found

 

下一个示例程序e_c14_p5.ada演示了如何从输入文件中读取字符串。与字符的方式大致相同,在输入文件中遇到行尾字符时将忽略。结果是,当运行第一个循环时,不会发出“回车”命令,并且所有文本都一起运行。但是,第二个循环使用lookahead方法,并在检测到输入流中的行结束时调用New_Line过程。

这个程序和上一个程序的最大区别在于,这里输入的是字符串类型变量,上一个使用的是字符类型变量。

 

我捉弄了你

这个程序有点小技巧。输入文件每行包含10个字符的精确倍数,字符串类型的输入变量包含10个字符。因此,读入十个字符的字符串没有实际问题,但是如果行不是十个字符的精确倍数,我们就会得到一个输入错误。如果您还记得在我们研究字符串时处理字符串变量有多困难,您就会明白我们这里也有同样的问题。当我们进入第16章及其示例程序时,我们将看到如何通过动态字符串例程的附加库极大地提高字符串功能。另外,ADA95有几个动态字符串包可供您使用。

一定要编译并运行这个程序,然后在名为字符.TXT以查看尝试读入一组奇怪的额外字符的结果。

 

现在读一些数字

Example program ------> e_c14_p6.ada

   -- Chapter 14 - Program 6
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;

procedure IntIn is

   Integer_File : FILE_TYPE;
   Index        : INTEGER;

begin

   Open(Integer_File, In_File, "INTDATA.TXT");

   while not End_Of_File(Integer_File) loop
      if End_Of_Line(Integer_File) then
         New_Line;
         Skip_Line(Integer_File);
      else
         Get(Integer_File, Index);
         Put("The value read in is");
         Put(Index, 6);
         New_Line;
      end if;
   end loop;

   Close(Integer_File);

end IntIn;




-- Result of execution

-- The value read in is    15
-- The value read in is    16
-- The value read in is    17
-- The value read in is    18
-- The value read in is    19
--
-- The value read in is    16
-- The value read in is    17
-- The value read in is    18
-- The value read in is    19
-- The value read in is    20
--
-- The value read in is    17
-- The value read in is    18
-- The value read in is    19
-- The value read in is    20
-- The value read in is    21

 

计算机很擅长处理数字,为了处理数字,我们必须有办法把数字输入计算机。示例文件e_c14_p6.ada说明了如何将整型数据从文件读入计算机。与前两个程序非常相似,我们打开一个文件进行读取,然后开始执行一个循环,每次通过循环读取一个整数类型的数字作为输入。我们正在读取一个整数类型数字,因为这是Index的类型,Get过程调用中的第二个实际参数。因为它是一个整数类型的数字,所以系统将开始扫描,直到找到一个以空格结尾的有效整数类型的数字。然后它将以计算机的内部格式返回分配给我们提供给它的变量的数字,并使它像任何其他整数类型的变量一样可供我们使用。如果输入文件在找到有效整数值之前遇到除整数类型数据以外的任何数据,则会引发异常,并终止程序。

循环以与前两个程序大致相同的方式继续,直到检测到文件结束,然后停止。在使用数字输入时还有一个细微的区别,系统不会读取行尾字符,因为它不知道如何读取。它在尝试读取下一个数据点时被卡住了,但始终无法到达,因为行尾阻塞了它。当检测到行尾时,或者在任何其他时间,您都可以发出函数Skip_Line,该函数告诉它转到下一行的开头以获取下一个输入数据。在任何时候,您都可以开始阅读下一行的下一个数据点。

请务必编译并运行此程序,然后更改输入文件中某些数字的间距,以查看它们是否以自由格式的间距读入。

 

浮点数据输入呢?

一旦了解了中读取整数类型数据的方法,就可以使用相同的方法读取中的任何其他类型。请记住,您读入的数据必须与要读入的变量的类型相同,这样您就不会有什么困难了。

 

用键盘阅读怎么样?

从键盘读取与从文件读取类似,只是它使用预定义的内部文件名,Standard_Input,如果省略文件名引用,输入将来自键盘。应该指出的是,当您按下return键时,操作系统可能会自动缓冲输入数据,并将其作为一个完整的字符串提供给您的程序。它将允许您输入一个包含任意多个整数值的完整字符串,当您点击return时,整个字符串将被输入和处理。

修改最后一个从键盘读取的文件,并在编译和运行后输入一些数字。请注意,从键盘读取End_Of_File没有结尾。使用具有固定传递次数的循环,或者使用无限循环并在输入特定次数(如-1)时退出。

 

如何在打印机上打印数据?

Example program ------> e_c14_p7.ada

  -- Chapter 14 - Program 7
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;

procedure PrintOut is

   Turkey : FILE_TYPE;

begin
                             -- First we create the file
   Create(Turkey, Out_File, "LPT1");
                             -- Then we write to it
   Put(Turkey, "This is a test of turkey");
   New_Line(Turkey);
   Put(Turkey, "and it should work well.");
   New_Line(Turkey, 2);
   Put("Half of the turkey test.");
   New_Line;

   Set_Output(Turkey);       -- Make Turkey the default output
      Put("This is another test of turkey");
      New_Line;
      Put("and it should work well.");
      New_Line(2);
      Put(Standard_Output, "Half of the turkey test.");
      New_Line(Standard_Output);
   Set_Output(Standard_Output); -- Return to the Standard default

   Put("Back to the standard default output.");

   Close(Turkey);

end PrintOut;




-- Results of execution

-- (Output to the monitor)
--
-- Half of the turkey test.
-- Half of the turkey test.
-- Back to the standard default output.

-- (Output to the printer)
--
-- This is a test of turkey
-- and it should work well.
--
-- This is another test of turkey
-- and it should work well.

名为e_c14_p7.ada的程序演示了如何将数据发送到打印机。将数据发送到打印机与将数据发送到磁盘文件的唯一区别是使用预定义的名称LPT1作为外部文件名。此文件定义为打印机而不是文件,从程序中可以看到,它的操作与任何其他文件都没有区别。

其他名称也可能适用于打印机,如PRN、COM1等。请检查文档中模拟文件的预定义名称。

确保打印机联机,然后编译并运行此程序。

 

TEXT IO PRAGMAS

pragma是对编译器的建议,根据Ada的定义,任何实现都可以忽略它。有关预定义pragmas  LIST and PAGE的定义,请参阅Ada 95参考手册(ARM)的附录L。由于这些可能不适用于任何特定的编译器,为了获得高度的程序可移植性,应该不鼓励使用它们。

 

页和行控制子程序

参考定义Ada.Text_IO文件在ARM的附录A.10.1中提供了大量用于Ada.Text_IO的页和行控制子程序。每个编译器都需要这些子程序,因此您应该研究它们,以深入了解任何Ada程序中可用的页和行控制子程序。在这些定义中,你不应该有太难理解的东西。

 

编程练习

1.修改e_c14_p4.ada以从键盘读取数据并将数据回显到监视器,直到输入Q为止。(Solution)

2.编写一个名为 FLOATIN.ADA从文件中读取浮点数据并显示它的。浮点输入没有标准。有些编译器要求小数点前后至少有一位数字。有些甚至可能不需要小数点,但会将其提供给看起来像整数值的输入。试验并确定编译器的特性。(Solution)

 

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

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

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

 

posted @ 2021-04-08 19:25  yangjianfeng  阅读(430)  评论(0编辑  收藏  举报