Ada file operation: instantiation and exception

2019-08-02 09:08发布

I'm learning Ada and I need some clarifications on file operations. I have just one type: float and I have to create 2 files that will store float values (with append operation). So I'm instantiating a package for the type float and I then declare 2 file variables X_File and Y_File. Then I put exceptions in case the files don't already exist.

WITH Ada.Text_IO;
WITH Ada.Sequential_IO;

PROCEDURE TestWrite6 IS
   PACKAGE Seq_Float_IO IS NEW Ada.Sequential_IO (Element_Type => Float);
   X_File : Seq_Float_IO.File_Type;
   Y_File : Seq_Float_IO.File_Type;


BEGIN

 Seq_Float_IO.Open (File => X_File, Mode => Seq_Float_IO.Append_File, 
 Name => "xvalues.dat");
 exception
 when Seq_Float_IO.Name_Error =>
  Seq_Float_IO.Create (File => X_File, Mode => Seq_Float_IO.Out_File, 
  Name =>  "xvalues.dat");

 Seq_Float_IO.Open (File => Y_File, Mode => Seq_Float_IO.Append_File, 
 Name => "yvalues.dat");
 exception
 when Seq_Float_IO.Name_Error =>
  Seq_Float_IO.Create (File => Y_File, Mode => Seq_Float_IO.Out_File, 
  Name => "yvalues.dat");

END TestWrite6;

I have two separate exceptions for each file xvalues.dat and yvalues.dat . Now on compiling, I get the error message:

16.
17.    Seq_Float_IO.Open (File => Y_File, Mode => Seq_Float_IO.Append_File, Name => "xvalues.dat");
18.    exception
       |
    >>> exception handler not permitted here

19.    when Seq_Float_IO.Name_Error =>

It seems that I can just have 1 exception for the xvalues.dat and not a second one for yvalues.dat. What am I doing wrong?

Thanks a lot...


Some modifications: write a general procedure to open and append values in a file:

WITH Ada.Sequential_IO;
WITH Ada.Float_Text_IO;

PROCEDURE TEST is

package Seq_Float_IO is new Ada.Sequential_IO (Element_Type => Float);
X_File : Seq_Float_IO.File_Type;


procedure Open_Data(File : in out Seq_Float_IO.File_Type; 
Name : in String) is

BEGIN

   begin
      Seq_Float_IO.Open (
         File => File,
         Mode => Seq_Float_IO.Append_File,
         Name =>  );
    exception
      when Seq_Float_IO.Name_Error =>
         Seq_Float_IO.Create (
           File => File,
           Mode => Seq_Float_IO.Out_File,
           Name =>  );
   end;

END Open_Data;


x        : CONSTANT Float := 2.0;


BEGIN --main program
   Open_Data(X_File, "xvalues.dat");
   Seq_Float_IO.Write(File => X_File,Item => x);

   Seq_Float_IO.Close(File => X_File);
END TEST;

In procedure Open_Data. I left the 2 fields for Name => blank as I don't know what to put in there.

And I also put File => File...this doesn't seem ok!!!

2条回答
唯我独甜
2楼-- · 2019-08-02 09:35

A given sequence of statements can only have one set of exception handlers. One approach is to wrap each handled sequence of statements in its own block, as shown below. Noting the common statements in each block, consider writing a short subprogram that can open or create a file by name and handle any exceptions that arise.

with Ada.Sequential_IO;

procedure TestWrite6 is
   package Seq_Float_IO is new Ada.Sequential_IO (Element_Type => Float);
   X_File : Seq_Float_IO.File_Type;
   Y_File : Seq_Float_IO.File_Type;

begin
   begin
      Seq_Float_IO.Open (
         File => X_File,
         Mode => Seq_Float_IO.Append_File,
         Name => "xvalues.dat");
   exception
      when Seq_Float_IO.Name_Error =>
         Seq_Float_IO.Create (
            File => X_File,
            Mode => Seq_Float_IO.Out_File,
            Name =>  "xvalues.dat");
   end;
   begin
      Seq_Float_IO.Open (
         File => Y_File,
         Mode => Seq_Float_IO.Append_File, 
         Name => "yvalues.dat");
   exception
      when Seq_Float_IO.Name_Error =>
         Seq_Float_IO.Create (
            File => Y_File,
            Mode => Seq_Float_IO.Out_File, 
            Name => "yvalues.dat");
   end;
end TestWrite6;
查看更多
迷人小祖宗
3楼-- · 2019-08-02 09:36

Follow-up question: You still need to have variables of type Seq_Float_IO.File_Type in TestWrite6. Given a method with this signature:

procedure Open_Data(File : in out Seq_Float_IO.File_Type; 
                    Name : in String) is

you'd need these declarations for the in out parameter:

X_File : Seq_Float_IO.File_Type;
Y_File : Seq_Float_IO.File_Type;

and you'd use them like this:

Open_Data(X_File, "xvalues.dat");
Open_Data(Y_File, "yvalues.dat");
Seq_Float_IO.Write(File => X_File, Item => ...);
Seq_Float_IO.Write(File => Y_File, Item => ...);
查看更多
登录 后发表回答