2

这个问题是帖子的后续内容

Ada 文件操作:实例化和异常

关于在 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;

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

  1. X_File : Seq_Float_IO.File_Type;
    1. 文件名:字符串;|

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

我不知道两件事:

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

文件名:常量字符串:=“one_File_Only.dat”

  1. 将过程 Open_Data 保存在单独的 ads 和 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。对不起,伙计们,我不知道该放什么。

非常感谢您的帮助。谢谢

4

2 回答 2

3

Ada 中的plainString是一个特定的字符串,比如 your File_Name,必须是固定长度的;但不同的字符串可以有不同的长度。

你可以写

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

在这种情况下,S1 的长度为 4,分配给它的长度必须为 4。你可以写

S1 := "abcd";

但是如果你尝试写

S1 := "pqrst";

或者

S1 := S2;

你会得到一个Constraint_Error.

对于子程序的 String 参数,例如您的Open_Data, String 参数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。第一个File是形式参数的名称,Seq_Float_IO.Open第二个File是要传递的内容,在本例中 Open_Data是 的File参数。

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

Open_Data (File => X_File, Name => "x.dat");
Open_Data (File => Y_File, Name => "a_very_long_name.dat");
于 2010-07-03T20:43:35.773 回答
2

@Simon Wright 的答案是正确的,您可能会发现将他的答案与我之前写的第二个答案进行比较会有所帮助。请注意,如果您有

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

字符串Name_XName_Y可以用作 的实际Name参数Open_Data。形参Name的类型为StringString是不受约束的,它可以是任何(实现定义的)最大长度。相比之下,Name_X每个Name_Y都有一个由初始分配确定的固定长度。

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

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

在实现中,您希望将接收到的作为实际参数 ( ) 转发给OpenStringName而不是全局常量的名称 ( Name_X)。

Seq_Float_IO.Open (
    File => File,
    Mode => Seq_Float_IO.Append_File,
    Name => Name );
于 2010-07-03T21:06:41.000 回答