ADAの他の文字列から文字列を作成するにはどうすればよいですか?
質問
ログファイルにヘッダーラインを出力し、次にデータの前に「 - 」の行を出力したいと思います。これを行うには、ヘッダーの文字列を作成し、同じ数の ' - 'を追い出します。
ただし、生成された文字列は1024文字ではないため、以下のコードは常にConstraint_Errorで失敗します。 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;
解決
階段で文字列を構築するCの方法に慣れている多くの人々は、ADAの弦の周りに心を包むのに苦労しています。 AS-ISを初期化して使用することになっています. 。 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;
(注:コメントは、ソーの色彩を軌道に戻すためのハックです)
同じ長さのセパレーターを持っている必要がなければ、変数を宣言する必要さえありません。
それが私だったら、私は持っているようなことをする Log_To_File
長さを追跡し、リクエストに応じて独自の適切なサイズのセパレーターを生成します。その後、あなたはただ書くことができます:
Open_Log();
Log_To_File ("# " & FLS(" Field1", 12) &
"|" & FLS(" Field2", 12) &
"|" & FLS(" Field3", 16));
Log_Separator_To_File;
他のヒント
文字列の代わりに、MSGを文字列として宣言するだけです(1 .. 1024)
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;
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;
便利な場合、stringコンストラクター機能を使用することができます Ada.Strings.Fixed
, Ada.Strings.Bounded
また Ada.Strings.Unbounded
. 。これらは *オペレーターを過負荷にして「文字を複製するか、指定された回数を文字列で複製します」。例えば、
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
...
Log_To_File("# " & Length(Msg) * '-');
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;