首页 文章

ada中的文件IO,如何将字符串写入文件?

提问于
浏览
3

关于将String变量写入文件有一些问题 . 问题是我必须指定该String的确切长度 . 否则输出文件将只包含一些废料值 . 我想知道这是否可以以某种方式解决,而无需事先告诉String的长度?

我知道我的 Get() 过程存储了该变量的长度,我只能将它返回给主程序 . 但是我想编写我的程序,所以它会在我开始写入out文件之前先从输入文件中读取所有内容 .

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时,将其打印到文件或屏幕时,不必绝对是字符串大小

3 回答

  • 0

    好吧,必须在某处跟踪字符串有效部分的长度 .

    您可以将每个记录的字符串字段的有效长度保持为单独的字段:

    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读取和写入的字符串之间来回转换 .

  • 6

    我个人只是按照Marc C的建议使用Unbounded_String,但是如果你想避免这种情况,你可以这样做:

    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;
    

    我将读写分为两个块,因为你说:

    ...在开始写入out文件之前,首先从输入文件中读取所有内容

    显然,使用此方法,您将必须适当地调整Buffer变量的大小 . 但实际上,与仅使用Unbounded_String相比,它非常笨拙 . 我会说,除非你有一些非常具体的问题或要求,否则Unbounded_String可能就是这样 . 它会极大地简化事情 .

    祝好运! :O)

  • 2

    一般来说,你可以逃脱,而不必在Ada中有一个特殊的“长度”变量 . 可悲的是,这种情况很难实现 .

    但是有一个技巧可以让你在这种情况下做到这一点 . 如果你不希望你的琴弦长得太长,或者你的琴弦会很慢 . 如果这听起来不错,请尝试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;
    

相关问题