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. File_Name:文字列; |

      制約のないサブタイプは許可されていません(初期化が必要)初期値または明示的な配列境界を提供します

私は2つのことを知りません:

  1. File_Name:String;があります。別のファイルに書き込めるようにしたいので。だから私は一般的な文字列が欲しいのですが、次のようなものではありません:

File_Name:CONSTANT 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が使用するパラメーターとしてName_Xを指定しましたが、Name_XまたはName_Yのいずれかである一般的な名前を渡すことができるはずなので、これは正しくありません。申し訳ありませんが、ここに何を入れるかわかりません。

よろしくお願いします。ありがとう

4

2 に答える 2

3

AdaのプレーンについてのことStringは、あなたのような特定の文字列はFile_Name固定長でなければならないということです。ただし、異なる文字列の長さは異なる場合があります。

あなたは書ける

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

この場合、S1の長さは4であり、S1への割り当ての長さは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部分を考えてみてください。1つ目Fileはの正式なパラメータの名前でSeq_Float_IO.Open、2つ目Fileは渡されるもの(この場合は Open_DataFileパラメータ)です。

上記の呼び出しを次のように書くことができたと指摘すると役立つかもしれません

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の答えは正しいので、彼の答えを私が以前に書いた2番目の答えと比較すると役立つ場合があります。あなたが持っていた場合は注意してください

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

文字列Name_XまたはName_Yのいずれかを、の実際のNameパラメータとして使用できますOpen_Data。正式なパラメータ、NameはタイプがStringです。Stringは制約なしであり、任意の(実装定義の)最大長にすることができます。対照的にName_XName_Yそれぞれの長さは、最初の割り当てによって決定されます。

補遺:この署名を持つName、型の仮パラメータ()を使用してサブプログラムを作成しましたString

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

実装では、グローバル定数()の名前ではなく、実際のパラメーター()として受け取ったものに転送する必要がOpenあります。StringNameName_X

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