كيف أقوم ببناء سلسلة من سلاسل أخرى في ADA؟

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

  •  20-09-2019
  •  | 
  •  

سؤال

أرغب في إخراج سطر رأس في ملف السجل ثم سطر "-" قبل البيانات. للقيام بذلك ، أقوم بإنشاء سلسلة من الرأس ثم تفوق على نفس العدد من "-".

لكن الرمز أدناه يفشل دائمًا باستخدام Crodent_error لأن السلسلة التي تم إنشاؤها ليست 1024 حرفًا. في واجبات سلسلة 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 ، يصبح الحل أبسط بكثير. يمكنني حتى رمي روتين "ملء" الخاص بك.

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 على المسار الصحيح)

إذا لم يكن لديك فاصل بنفس الطول ، فلن تحتاج حتى إلى إعلان المتغير.

لو كان الأمر أنا ، سأفعل شيئًا مثل 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) * '-');

لقد عملت على كيفية استخدام undounded_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