Pregunta

Quiero generar una línea de encabezado en un archivo de registro y luego una línea de '-' antes de los datos. Para hacer esto, creo una cadena del encabezado y luego supero el mismo número de '-'.

Pero el siguiente código siempre falla con una restricción_error porque la cadena generada no es de 1024 caracteres. En las asignaciones de cadenas ADA requieren exactamente la misma longitud no solo suficiente capacidad.

La opción 1) es calcular la longitud exacta, pero eso es frágil para los cambios futuros. La opción 2) es usar algo más que cadena.

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;
¿Fue útil?

Solución

Muchas personas que están acostumbradas a la forma de construir cuerdas en pasos tienen problemas para envolver sus mentes alrededor de las cuerdas de Ada, que se supone que debes inicializar y usar como es. Cuando convierte este hecho sobre las cadenas de ADA, la solución se vuelve mucho más simple. Incluso puedo tirar tu rutina de "llenar".

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;

(Nota: el comentario es un truco para volver a la pista de Colorizador de SO)

Si no tuviera que tener el separador de la misma longitud, ni siquiera necesitaría declarar la variable.

Si fuera yo, haría algo como tener Log_To_File Realice un seguimiento de las longitudes y genere su propio separador de tamaño adecuado a pedido. Entonces podrías escribir:

Open_Log();
Log_To_File ("# " & FLS(" Field1", 12) & 
       "|" & FLS(" Field2", 12) & 
       "|" & FLS(" Field3", 16)); 
Log_Separator_To_File;

Otros consejos

Simplemente declare MSG como una cadena en lugar de una cadena (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;

Un enfoque podría ser escribir una función que llene una cadena de longitud fija con una cadena de entrada de tamaño dinámico, acolchado con espacios:

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;

El manejo de cadenas de ADA le permite pasar cualquier búfer de longitud fija a Dest y el 'First y 'Last Los atributos serán correctos dentro del cuerpo del procedimiento.

Entonces, su código podría convertirse:

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;    

Como conveniencia, puede usar las funciones del constructor de cadenas en Ada.Strings.Fixed, Ada.Strings.Bounded o Ada.Strings.Unbounded. Estos sobrecargan el operador * para "replicar un carácter o caducar un número especificado de veces". Por ejemplo,

with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
   ...
   Log_To_File("# " & Length(Msg) * '-');

Me resolví cómo usar Unbounded_String. Ese tipo aceptará otras cuerdas de tamaño.

No puede construir una cadena ilimitada con el operador & a menos que esté utilizando cadenas ilimitadas, así que use la función 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; 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top