Ada: Input/Output

Ada's I/O library is typed and generic: there is one I/O package family per kind of thing you read or write, each with compile-time-checked operations and named exceptions. Text I/O, file I/O, and streams share one model, so learning it once covers everything.

Text I/O

Ada.Text_IO handles console and text files. Its Put/Put_Line take a String; other types go through 'Image or generic child packages:

with Ada.Text_IO; use Ada.Text_IO;

procedure Text_Demo is
begin
   Put ("count: ");                        -- no newline
   Put_Line (Integer'Image (42));          -- 42 + newline
   --  Put_Line (42);                      -- compile error: not a String
end Text_Demo;

The generic children format values with widths — Ada.Integer_Text_IO for integers, Ada.Float_Text_IO for reals:

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

procedure Format_Demo is
begin
   Put (42, Width => 6);        -- "    42" right-aligned in 6 columns
   Put (42, Width => 0);        -- "42" — natural width
   New_Line;
end Format_Demo;

Reading Input

Get_Line reads a line of text into a buffer and reports how much it filled — no buffer overruns, ever:

with Ada.Text_IO; use Ada.Text_IO;

procedure Input_Demo is
   Buffer : String (1 .. 80);
   Last   : Natural;
begin
   Put ("your name: ");
   Get_Line (Buffer, Last);            -- fills Buffer, sets Last to the used end
   Put_Line ("hello, " & Buffer (1 .. Last));   -- slice to the actual length
end Input_Demo;

Reading typed values uses the generic Get: Integer_Text_IO.Get (N) skips whitespace, parses an integer, and raises Data_Error on garbage — a catchable event, not UB.

Files

File I/O uses the same package with explicit File_Type handles. Opening failures are exceptions you handle locally:

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Exceptions; use Ada.Exceptions;

procedure File_Demo is
   F : File_Type;
begin
   begin
      Open (F, In_File, "data.txt");
   exception
      when E : Name_Error =>          -- file missing or unusable
         Put_Line ("cannot open data.txt: " & Exception_Message (E));
         return;
   end;

   while not End_Of_File (F) loop
      declare
         Line : String (1 .. 256);
         Last : Natural;
      begin
         Get_Line (F, Line, Last);
         Put_Line (Line (1 .. Last));
      end;
   end loop;
   Close (F);
end File_Demo;

Text files, direct-access files (Ada.Direct_IO), and streams (Ada.Streams) share this open/read/write/close shape. Streams additionally serialize whole objects — including nested records — with one call, which is how Ada programs save state without hand-rolled serializers.

The Exception Model in I/O

Every I/O failure has a named exception: Name_Error (bad file name), Use_Error (file not open for that direction), Data_Error (unparseable content), End_Error (read past end). The compiler cannot force you to handle them, but the run time refuses to continue silently — the next lesson (Packages) formalizes how handlers compose. Next: Packages.