7

ログ ファイルにヘッダー行を出力し、データの前に「-」の行を出力したい。これを行うには、ヘッダーの文字列を作成し、同じ数の「-」を出力します。

ただし、生成された文字列が 1024 文字ではないため、以下のコードは常に CONSTRAINT_ERROR で失敗します。In Ada 文字列の割り当てには、十分な容量だけでなく、まったく同じ長さが必要です。

オプション 1) は正確な長さを計算することですが、これは将来の変更に対して脆弱です。オプション 2) は、文字列以外のものを使用することです。

procedure F() is 
    Msg : String(1..1024);
begin
    Open_Log();
    Msg :=       FLS(" Field1", 12) &
           "|" & FLS(" Field2", 12) &
           "|" & FLS(" Field3", 16);

    Log_To_File("# " & Msg);
    Log_To_File("# " & Fill_String(Msg'Last, '-'));
end;
4

5 に答える 5

6

文字列を段階的に構築する C の方法に慣れている多くの人々は、初期化してそのまま使用することになっているAda 文字列に頭を悩ませています。Ada 文字列に関するこの事実を理解すると、解決策ははるかに簡単になります。あなたの「塗りつぶし」ルーチンを捨てることさえできます。

procedure F() is  
   Msg : constant String
      := FLS(" Field1", 12) & 
       "|" & FLS(" Field2", 12) & 
       "|" & FLS(" Field3", 16); 
   Separator : constant String := (1..Msg'length => '-'); --'
begin 
   Open_Log(); 

   Log_To_File("# " & Msg); 
   Log_To_File("# " & Separator); 
end;

(注: コメントは、SO のカラーライザーを元に戻すためのハックです)

区切り記号を同じ長さにする必要がなければ、変数を宣言する必要さえありません。

それが私だったら、Log_To_File長さを追跡し、要求に応じて独自の適切なサイズのセパレーターを生成するようなことをします。次に、次のように書くことができます。

Open_Log();
Log_To_File ("# " & FLS(" Field1", 12) & 
       "|" & FLS(" Field2", 12) & 
       "|" & FLS(" Field3", 16)); 
Log_Separator_To_File;
于 2010-02-17T13:42:40.900 に答える
4

MsgをString(1 .. 1024)ではなくStringとして宣言するだけです

procedure F() is 

    Msg: String  
    :=       FLS(" Field1", 12) &
       "|" & FLS(" Field2", 12) &
       "|" & FLS(" Field3", 16);
    --// this 'magically' declares Msg as a String(1 .. Something)
    --// with the right Something

begin
   Open_Log();

   Log_To_File("# " & Msg);
   Log_To_File("# " & Fill_String(Msg'Last, '-')); --'
end;
于 2010-02-17T13:25:43.370 に答える
3

1つのアプローチは、固定長の文字列を動的なサイズの入力文字列で埋め、スペースを埋める関数を作成することです。

procedure Pad_String(Str: in String; Dest: out String; Len: out Integer) is
begin
    Len := Str'Last - Str'First + 1;
    Dest(Dest'First .. Dest'First + Len - 1) := Str(Str'First .. Str'First + Len - 1);
    Dest(Dest'First + Len .. Dest'Last) := Fill_String(Dest'Last - Len, ' ');
end Pad_String;

Adaの文字列処理により、任意の固定長バッファをに渡すことができDest'Firstおよび'Last属性はプロシージャの本体内で正しくなります。

次に、コードは次のようになります。

procedure F() is     
    Msg : String(1..1024);    
    Len : Integer;
begin    
    Open_Log();    
    Pad_String(      FLS(" Field1", 12) &    
               "|" & FLS(" Field2", 12) &    
               "|" & FLS(" Field3", 16),
               Msg,
               Len);

    Log_To_File("# " & Msg(1 .. Len));    
    Log_To_File("# " & Fill_String(Len, '-'));    
end;    
于 2010-02-15T02:45:29.567 に答える
2

Ada.Strings.Fixed便宜上、 、Ada.Strings.Boundedまたはで String コンストラクター関数を使用できますAda.Strings.Unbounded。これらは * 演算子をオーバーロードして、「指定された回数だけ文字または文字列を複製します」。例えば、

with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
   ...
   Log_To_File("# " & Length(Msg) * '-');
于 2010-02-16T05:27:06.773 に答える
1

Unbounded_String の使用方法を考え出しました。そのタイプは、他のサイズの文字列を受け入れます。

無制限の文字列を使用しない限り、& 演算子を使用して無制限の文字列を作成することはできないため、To_Unbounded_String 関数を使用します。

with Ada.Strings.Unbounded;
procedure F() is  
   use Ada.Strings.Unbounded;
   Msg : Unbounded_String;
begin 
   Open_Log(); 
   Msg := Ada.Strings.Unbounded.To_Unbounded_String(
                FLS(" Field1", 12) & 
          "|" & FLS(" Field2", 12) & 
          "|" & FLS(" Field3", 16)); 

   Log_To_File("# " & Ada.Strings.Unbounded.To_String(Msg)); 
   Log_To_File("# " &
          Fill_String(Ada.Strings.Unbounded.Length(Msg), '-')); 
end; 
于 2010-02-15T06:05:32.750 に答える