2010-02-15 78 views
7

我想在日誌文件中輸出標題行,然後在數據前輸出一行「 - 」。爲此,我創建一個標題的字符串,然後輸出相同數量的' - '。如何從Ada中的其他字符串構建字符串?

但是下面的代碼總是失敗並帶有CONSTRAINT_ERROR,因爲生成的字符串不是1024個字符。在Ada中,字符串分配需要完全相同的長度,而不僅僅是足夠的容量。選項1)計算確切的長度,但對未來的變化很脆弱。 選項2)是使用除String之外的其他東西。

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; 

回答

6

很多的人誰是用來建設字符串的C-方式的步驟有麻煩纏繞在Ada字符串周圍,你應該初始化並使用原樣是。當你對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; 
+0

+1主張另一種思維方式;不錯的着色劑破解! – trashgod

3

一種做法是寫填充固定長度字符串動態分級的輸入字符串的函數,填充帶有空格:

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; 

阿達的字符串處理允許你通過任何固定長度的緩衝區分成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;  
+0

奇怪。如果你正在跟蹤長度和切片,爲什麼還要在切片外面「墊」? –

+1

@ T.E.D。:如果你始終初始化'Dest'字符串的其餘部分,'Pad_String'函數在一般情況下更有用。另外最好不要留下未初始化的數據; Ada程序員往往非常保守。 –

1

我制定瞭如何使用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; 
+1

這會工作,但它是不乾淨的。用簡單的舊Ada字符串,你可以做得很好,而且簡單得多。 –

2

爲方便起見,可以在Ada.Strings.FixedAda.Strings.BoundedAda.Strings.Unbounded使用String構造函數。這些將*運算符重載爲「按指定的次數複製字符或字符串」。例如,

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

是的,但你可以通過簡單的字符串聲明和'others =>'-''初始化完成同樣的事情。 –

+1

僅僅是一個人選擇的字符串模型的便利。 – trashgod

3

剛宣佈消息的字符串,而不是一個字符串(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; 
+0

啊啊是的!代表用戶的正確答案是1.您剛剛完成了我的一天,斯蒂芬。 –

+0

我很喜歡它,所以我重新格式化了一下,讓SO的代碼查看器小工具更好地顯示它。如果你不喜歡它,請隨時恢復它。 –

+0

在我的代碼中的另一個地方,我需要在循環內部構建一個字符串。這將在一個函數decleration工作,但我怎麼做一個循環內? –

相關問題