Wie baue ich eine Schnur aus anderen Zeichenfolgen in ADA?
Frage
Ich möchte eine Kopfzeile in einer Protokolldatei und dann eine Zeile von '-' vor den Daten ausgeben. Dazu erstelle ich eine Zeichenfolge des Headers und übertäuscht dann die gleiche Anzahl von '-'.
Der folgende Code schlägt jedoch immer mit einem Constraint_error fehl, da die generierte Zeichenfolge nicht 1024 Zeichen beträgt. In ADA -Zeichenfolgen erfordern Zuweisungen genau die gleiche Länge, nicht nur ausreichend Kapazität.
Option 1) besteht darin, die genaue Länge zu berechnen, aber das ist spröde für zukünftige Änderungen. Option 2) ist, etwas anderes als String zu verwenden.
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;
Lösung
Viele Leute, die es gewohnt sind, Stufen in Stufen zu bauen Sie sollen initialisieren und as-is verwenden. Wenn Sie diese Tatsache über ADA -Zeichenfolgen gruken, wird die Lösung viel einfacher. Ich kann sogar Ihre "Füllroutine" wegwerfen.
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;
(Hinweis: Der Kommentar ist ein Hack, um den Colorizer von So's wieder auf dem richtigen Weg zu bringen)
Wenn Sie das Trennzeichen nicht gleich lang haben müssten, müssten Sie nicht einmal die Variable deklarieren.
Wenn ich es wäre, würde ich so etwas wie haben Log_To_File
Behalten Sie die Längen im Auge und generieren Sie auf Anfrage einen eigenen entsprechenden Trennzeichen. Dann konnten Sie einfach schreiben:
Open_Log();
Log_To_File ("# " & FLS(" Field1", 12) &
"|" & FLS(" Field2", 12) &
"|" & FLS(" Field3", 16));
Log_Separator_To_File;
Andere Tipps
Deklary MSG einfach als Zeichenfolge anstelle einer Zeichenfolge (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;
Ein Ansatz könnte darin bestehen, eine Funktion zu schreiben, die eine feste Länge -Zeichenfolge mit einer dynamisch großen Eingangszeichenfolge ausfüllt, die mit Leerzeichen gepolstert wird:
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;
Mit der ADA -Saitenhandhabung können Sie einen beliebigen Puffer fester Länge übergeben Dest
und die 'First
und 'Last
Die Attribute sind im Körper des Verfahrens korrekt.
Dann könnte Ihr Code werden:
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;
Als Komfort können Sie die String -Konstruktorfunktionen in verwenden Ada.Strings.Fixed
, Ada.Strings.Bounded
oder Ada.Strings.Unbounded
. Diese überlasten den * Operator, um "ein Zeichen oder eine bestimmte Anzahl von Male zu replizieren". Zum Beispiel,
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
...
Log_To_File("# " & Length(Msg) * '-');
Ich habe herausgefunden, wie man unbegrenzte_String verwendet. Dieser Typ akzeptiert andere Saiten.
Sie können mit dem & Bediener eine unbegrenzte Zeichenfolge nicht erstellen, es sei denn, Sie verwenden unbegrenzte Zeichenfolgen. Verwenden Sie also die Funktion to_unbundound_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;