views:

38

answers:

2

Hi, 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!!!

+1  A: 

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;
trashgod
Thanks. It works! Good to know about the block statement.
yCalleecharan
Yes I shall also investigate how to create a suitable subprogram or procedure.
yCalleecharan
Excellent! BTW, `subprogram` is an Ada term for either a function or procedure. Because `File_Type` is limited private, a procedure will be more straightforward. For example, `procedure Open_Data(File : in out Seq_Float_IO.File_Type; Name : in String) is ...`
trashgod
Thanks. See the code that I made (at the bottom of my post). It doesn't compile. It would be very kind of you if you would shed some light.
yCalleecharan
@yCalleecharan: For clarity, I've responded in a separate answer.
trashgod
A: 

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 => ...);
trashgod
Thanks again. I modified the code as shown at the bottom of my post (I deleted the previous code). I still don't know what to put in Name => as I wrote up in my post. I'm passing in a String...is it the file name?
yCalleecharan
And I also put File => File...this doesn't seem ok!!!
yCalleecharan
I've created another post for this question:http://stackoverflow.com/questions/3172364/procedure-to-open-write-and-append-in-ada
yCalleecharan