2011-06-26 20 views
3

我有一些關於將String變量寫入文件的問題。 問題是我必須指定該字符串的確切長度。否則輸出文件將只包含一些廢料值。我不知道這是否可以以某種方式解決,而無需事先告訴字符串的長度?在ada中的文件IO,如何將字符串寫入文件?

我知道我的Get()過程存儲該變量的長度,我只是可以將它返回給主程序。但是,我想寫我的程序,以便在開始寫入輸出文件之前,先執行從輸入文件中讀取的所有內容。

with Ada.Text_Io, Ada.Integer_Text_Io; 
use Ada.Text_Io,Ada.Integer_Text_Io; 

procedure Uppgift is 

    type Bil_Register is 
     record 
    Namn : String(1..50); 
    Adress : String(1..50); 
    Post : String(1..50); 
    Reg  : String(1..6); 
     end record; 

    Infil : File_Type; 
    Utfil  : File_Type; 
    L, I : Integer; 

    Br : Bil_Register; 

    procedure Get(F : in out File_Type; Br : out Bil_Register) is 
     Length : Integer; 
    begin 
     Get_Line(F, Br.Namn, Length);  
    end; 

begin 

    Open(Infil, In_File, "register.txt"); 
    Create(Utfil, Out_File, "test.txt"); 

    Get(Infil, Br); 
    Put_Line(Utfil, Br.Namn); 

    Close(Infil); 
    Close(Utfil); 

end Uppgift; 

-

EDIT(2011.08.20)

這似乎是隻有基於Unix操作系統的問題。當你使用Windows時,當你將它打印到文件或屏幕上時,你不必絕對使用字符串大小。

回答

6

那麼,字符串的有效部分的長度必須跟蹤某處

你可以保持您的每一個記錄的字符串域的有效長度作爲一個獨立的領域:

Namn  : String (1..50); 
Namn_Length : Natural; 

你可以定義自己的變量字符串型封裝,或者使用預先存在的,如Variable_Length。例如。

Namn : Variable_Length.Variable_String(50); 

您可以使用Unbounded_String的字段和變量:

Namn : Unbounded_String; 

而且Ada.Text_IO.Unbounded_IO的I/O:

with Ada.Strings.Unbounded; 
use Ada.Strings.Unbounded; 
with Ada.Text_IO.Unbounded_IO; 

procedure UTIO_Demo is 

    use Ada.Text_IO; 

    F : Ada.Text_IO.File_Type; 
    Data : Unbounded_String := To_Unbounded_String("Output by Unbounded_IO"); 

begin 
    Create(F, Ada.Text_IO.Out_File, "utio.tst"); 

    Unbounded_IO.Put_Line(F, Data); 

    Close(F); 
end UTIO_Demo; 

如果你不希望使用Unbounded_IO包,使用To_String和To_Unbounded_String在Unbounded_String值和通過Text_IO讀取和寫入的字符串之間來回轉換。

+0

你碰巧使用Unbounded_String與文件I/O時,有一些例子嗎?我無法讓它工作。 – starcorn

+0

我編輯了一個快速演示,我扔在一起的問題。請注意,您正在使用的文件是Ada.Text_IO的File_Type。 –

2

我個人只使用Unbounded_String,由Marc C作爲建議,但如果你想避免這種情況,你可以做這樣的事情:

with Ada.Text_IO; 
with Ada.Containers.Indefinite_Doubly_Linked_Lists; 

use Ada.Text_IO; 
use Ada.Containers; 

procedure Uppgift is 

    type Bil_Register (Namn_Length : Natural) is 
     record 
     Namn : String (1 .. Namn_Length); 
     -- Other components removed for brevity. 
     end record; 

    package BR_Container is new Indefinite_Doubly_Linked_Lists (Bil_Register); 
    use BR_Container; 

    BR_List  : BR_Container.List; 
    BR_List_Cursor : BR_Container.Cursor; 
    Buffer   : String (1 .. 100); 
    Length   : Natural; 
    Register_File : File_Type; 
    Test_File  : File_Type; 

begin 

    -- First we read the contents of register.txt and add all the data to 
    -- our list of Bil_Register objects. 
    Open (File => Register_File, 
     Mode => In_File, 
     Name => "register.txt"); 

    while not End_Of_File (File => Register_File) loop 
     Get_Line (File => Register_File, 
       Item => Buffer, 
       Last => Length); 
     declare 
     BR : Bil_Register 
      (Namn_Length => Length); 
     begin 
     BR.Namn := Buffer (1 .. Length); 
     BR_List.Append (New_Item => BR); 
     end; 
    end loop; 

    Close (File => Register_File); 

    -- Then we output the contents of our list of Bil_Register objects to 
    -- test.txt 
    Create (File => Test_File, 
      Mode => Out_File, 
      Name => "test.txt"); 

    BR_List_Cursor := BR_List.First; 
    while Has_Element (Position => BR_List_Cursor) loop 
     Put_Line (File => Test_File, 
       Item => Element (Position => BR_List_Cursor).Namn); 
     Next (Position => BR_List_Cursor); 
    end loop; 

    Close (File => Test_File); 

end Uppgift; 

我已經四分五裂讀寫兩大塊,因爲你說:

...做所有的從輸入讀取文件 第一之前,我開始寫 出文件

很明顯,用這種方法,你將不得不適當地調整Buffer變量的大小。但實際上,這與使用Unbounded_String相比非常笨拙。我會說,除非你有一些非常具體的問題或要求,否則Unbounded_String可能是一種方法。它將極大地簡化事情。

祝你好運!:o)

0

一般來說,您可以在Ada中不需要特殊的「長度」變量就可以離開。可悲的是,這種情況很難實現。

然而,在這種情況下,有一個技巧可以讓你做到。如果你不介意一點點遞歸,或者不要期望你的字符串很長,或者不關心執行速度太快(無論如何你都在做一個I/O,所以它會變慢) 。如果這聽起來不錯,請嘗試Carlisle's trick

function Next_Line(File : in Ada.Text_IO.File_Type := 
    Ada.Text_Io.Standard_Input) return String is 
    Answer : String(1..256); 
    Last : Natural; 
begin 
    Ada.Text_IO.Get_Line(File => File, 
     Item => Answer, 
     Last => Last); 
    if Last = Answer'Last then 
     return Answer & Next_Line(File); 
    else 
     return Answer(1..Last); 
    end if; 
end Next_Line; 

現在你可以改變你的代碼:

begin 

    Open(Infil, In_File, "register.txt"); 
    Create(Utfil, Out_File, "test.txt"); 

    Put_Line(Utfil, Next_Line (Infil)); 

    Close(Infil); 
    Close(Utfil); 

end Uppgift; 
+0

我試圖使用unbounded_string,但是我得到一些抱怨,我試圖使用它,但它收到了一個正常的字符串,而不是..你不會有一個簡單的例子如何使用它的文件讀/寫? – starcorn