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.