ADA의 다른 문자열에서 문자열을 만드는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/2263512

  •  20-09-2019
  •  | 
  •  

문제

로그 파일에서 헤더 라인을 출력 한 다음 데이터 전에 '-'라인을 출력하고 싶습니다. 이를 위해 헤더 문자열을 만든 다음 같은 수의 '-'를 능가합니다.

그러나 생성 된 문자열이 1024자가 아니기 때문에 아래 코드는 항상 제한 조건 _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;
도움이 되었습니까?

해결책

계단에서 현을 만드는 방법에 익숙한 많은 사람들은 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;

(참고 : 댓글은 So의 Colorizer를 다시 얻는 해킹입니다)

분리기를 같은 길이로 가질 필요가 없다면 변수를 선언 할 필요조차 없습니다.

그것이 나라면, 나는 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;

한 가지 방법은 동적 크기의 입력 문자열로 고정 길이 문자열을 채우고 공백으로 패딩하는 기능을 작성하는 것입니다.

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;    

편의로 문자열 생성자 함수를 사용할 수 있습니다. Ada.Strings.Fixed, Ada.Strings.Bounded 또는 Ada.Strings.Unbounded. 이들은 * 연산자에게 "캐릭터를 복제하거나 지정된 횟수의 숫자"를 과부하시킵니다. 예를 들어,

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

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; 
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top