首页 文章

在Ada中打开,写入和附加的过程

提问于
浏览
2

这个问题是该职位的后续跟进

Ada file operation: instantiation and exception

关于写入Ada中的文件 .

我选择将这个问题放在一个单独的帖子中,以便更多人可以看到它,因为我已经在上述帖子中接受了一个稍微不同的问题(文件处理中的异常)的答案 .

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;
File_Name : String;


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 => File_Name );
   exception
      when Seq_Float_IO.Name_Error =>
      Seq_Float_IO.Create (
         File => File,
         Mode => Seq_Float_IO.Out_File,
         Name => 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;

在编译上面我得到一个错误如下:

  • X_File:Seq_Float_IO.File_Type;

  • File_Name:String; |

不受约束的子类型不允许(需要初始化)提供初始值或显式数组边界

我不知道两件事:

  • 我有File_Name:String;因为我希望能够写入不同的文件 . 所以我想要一个通用的字符串,而不是像:

File_Name:CONSTANT String:=“one_File_Only.dat”

  • 将Open_Data程序保存在单独的广告和adb(用于正文)文件中会更好吗?

非常感谢...


新...

我修改了代码如下:

WITH Ada.Sequential_IO;

PROCEDURE TEST1 is

package Seq_Float_IO is new Ada.Sequential_IO (Element_Type => Float);
X_File, Y_File : Seq_Float_IO.File_Type;
Name_X : CONSTANT String := "domainvalues.dat";
Name_Y : CONSTANT String := "ordinatevalues.dat";


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 => Name_X );
    exception
      when Seq_Float_IO.Name_Error =>
         Seq_Float_IO.Create (
            File => File,
            Mode => Seq_Float_IO.Out_File,
            Name => Name_X);
   end;

END Open_Data;


x        : CONSTANT Float := 2.0;


BEGIN --main program
   Open_Data(File => X_File, Name => Name_X);
   Seq_Float_IO.Write(File => X_File, Item => x);
   Seq_Float_IO.Close(File => X_File);

   Open_Data(File => Y_File, Name => Name_Y);
  Seq_Float_IO.Write(File => Y_File, Item => x);
  Seq_Float_IO.Close(File => Y_File);

END TEST1;

如你所见

Seq_Float_IO.Open (
             File => File,
             Mode => Seq_Float_IO.Append_File,
             Name => Name_X );

我已将Name_X作为Name所采用的参数,但这不正确,因为我应该能够传入一个通用名称,可以是Name_X或Name_Y . 对不起伙计们,我无法弄清楚要放在这里的东西 .

我非常感谢你的帮助 . 谢谢

2 回答

  • 2

    在Ada中关于普通 String 的事情是,特定的字符串,如 File_Name ,必须是固定长度的;但不同的字符串可以有不同的长度 .

    你可以写

    S1 : String := "1234";
    S2 : String := "12345";
    

    在这种情况下,S1的长度为4,并且对它的赋值必须是长度为4.您可以编写

    S1 := "abcd";
    

    但如果你试着写

    S1 := "pqrst";
    

    要么

    S1 := S2;
    

    你会得到 Constraint_Error .

    对于子程序的字符串参数,例如 Open_Data ,字符串参数 Name 取长度 - 当然还有值!调用中的实际参数 . 所以你可以说

    Open_Data (X_File, "x.dat");
    Open_Data (Y_File, "a_very_long_name.dat");
    

    你之前遇到过问题

    procedure Open_Data(File : in out Seq_Float_IO.File_Type; 
                        Name : in String) is
    begin
       Seq_Float_IO.Open (File => File,
                          Mode => Seq_Float_IO.Append_File,
                          Name => ????);
    

    我不愿意只是告诉你答案,所以 - 考虑 File => File 部分 . 第一个 FileSeq_Float_IO.Open 的形式参数的名称,第二个 File 是要传递的内容,在本例中是 Open_DataFile 参数 .

    如果我指出我可以将上面的调用写为

    Open_Data (File => X_File, Name => "x.dat");
    Open_Data (File => Y_File, Name => "a_very_long_name.dat");
    
  • 3

    @Simon Wright的回答是正确的,你可能会发现将他的回答与我之前写的second one进行比较是有帮助的 . 请注意,如果你有

    Name_X : constant String := "domainvalues.dat";
    Name_Y : constant String := "ordinatevalues.dat";
    

    字符串 Name_XName_Y 可以用作 Open_Data 的实际 Name 参数 . 形式参数 Name 的类型为 String . String 是不受约束的,它可以是任何(实现定义的)最大长度 . 相比之下, Name_XName_Y 各自具有由其初始分配确定的固定长度 .

    附录:您编写了一个带有 String 类型的形式参数( Name )的子程序,具有此签名

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

    在实现中,您希望转发 Open 收到的 String 作为实际参数( Name ),而不是全局常量的名称( Name_X ) .

    Seq_Float_IO.Open (
        File => File,
        Mode => Seq_Float_IO.Append_File,
        Name => Name );
    

相关问题