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;
War es hilfreich?

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; 
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top