
This language feature is available from Ada 95 on. Ada.Text_IO is a unit of the Predefined Language Environment since Ada 95.
Description
The package Text_IO is used for simple Input Output (I/O) in text format.
Tips and Tricks for Text_IO
Read a whole line from the console
Ada 2005 has a function Get_Line which returns a newly created string containing the whole line:
functionGet_LinereturnString;
With older Ada generations, you need a little work to get the complete line with one call.
The Get_Line procedure gets a line of text of as many characters the Item can hold
or up to the new_line indicator, whichever comes first. (The new_line indicator's representation is
implementation defined.)
It has the following specification:
procedureGet_Line (Item:outString; Last:outNatural);
To be specific, consider an Item that can hold as much as 80 characters. Let's take two lines to read, one holding less that 80 characters, say 10, the other at least 80, perhaps more. Calling
Get_Line (Item, Last);
will read the first line up to the new_line indicator and consume them; Item's first 10 characters will be filled with the text read, the rest is junk; Last will hold the last filled index.
The next call will read the maximum Item can hold, i.e. 80 characters; the rest of the line (if any) and the
new_line indicator remain unconsumed.
Thus Last will be Item'First - 1 + 80.
In order to consume the rest of the line, you have to call Get_Line again.
The result will be like one of the two possibilities above, depending on the remaining line length.
If no characters are read (i.e. when the new_line indicator is the only thing left unread), Last will hold
value Item'First - 1.
The following example shows how the complete line could be read:
withAda.Text_IO;withAda.Strings.Unbounded;functionGet_LinereturnStringispackageUstrrenamesAda.Strings.Unbounded;packageT_IOrenamesAda.Text_IO; Everything: Ustr.Unbounded_String := Ustr.Null_Unbounded_String; Item : String (1 .. 80); Last : Natural;beginGet_Whole_Line:loopT_IO.Get_Line (Item, Last); -- * Ustr.Append (Source => Everything, New_Item => Item (1 .. Last)); -- *exitGet_Whole_LinewhenLast < Item'Last; -- **endloopGet_Whole_Line;returnUstr.To_String (Everything);endGet_Line;
As an exercise, change the calls at (*) to
T_IO.Get_Line (Item (11 .. 20), Last); Ustr.Append (Source => Everything, New_Item => Item (11 .. Last));
and see which values Item and Last will hold. Which criterium will you then need to exit the loop at (**)?
(This is of course not a very sensible idea to code like this, but as a learning instruction, it's fine.)
Read a whole line from a file
In principle it is the same as in console reading but you have to check for the end of file as well:
exitGet_Whole_LinewhenLast < Item'LastorT_IO.End_Of_File (File);
End_of_File is always False for console input (except when you manage to enter the implementation defined end_of_file indicator).
A well-formed text file (i.e. one created with Ada.Text_IO) will always hold an end_of_line (and an end_of_page) indicator before the
end_of_file indicator (see procedure Close).
Generic nested packages
Ada.Text_IO has the following nested packages for input/output of scalar types. The only parameter is the involved type.
- Decimal_IO
- Enumeration_IO
- Fixed_IO
- Float_IO
- Integer_IO
- Modular_IO
Specification
-- Standard Ada library specification -- Copyright (c) 2003-2018 Maxim Reznik <reznikmm@gmail.com> -- Copyright (c) 2004-2016 AXE Consultants -- Copyright (c) 2004, 2005, 2006 Ada-Europe -- Copyright (c) 2000 The MITRE Corporation, Inc. -- Copyright (c) 1992, 1993, 1994, 1995 Intermetrics, Inc. -- SPDX-License-Identifier: BSD-3-Clause and LicenseRef-AdaReferenceManual -- -------------------------------------------------------------------------withAda.IO_Exceptions;packageAda.Text_IOistypeFile_Typeislimitedprivate;typeFile_Modeis(In_File, Out_File, Append_File);typeCountisrange0 .. implementation_defined;subtypePositive_CountisCountrange1 .. Count'Last; Unbounded :constantCount := 0; -- line and page lengthsubtypeFieldisIntegerrange0 .. implementation_defined;subtypeNumber_BaseisIntegerrange2 .. 16;typeType_Setis(Lower_Case, Upper_Case); -- File ManagementprocedureCreate (File :inoutFile_Type; Mode :inFile_Mode := Out_File; Name :inString := ""; Form :inString := "");procedureOpen (File :inoutFile_Type; Mode :inFile_Mode; Name :inString; Form :inString := "");procedureClose (File :inoutFile_Type);procedureDelete (File :inoutFile_Type);procedureReset (File :inoutFile_Type; Mode :inFile_Mode);procedureReset (File :inoutFile_Type);functionMode (File :inFile_Type)returnFile_Mode;functionName (File :inFile_Type)returnString;functionForm (File :inFile_Type)returnString;functionIs_Open(File :inFile_Type)returnBoolean; -- Control of default input and output filesprocedureSet_Input (File :inFile_Type);procedureSet_Output(File :inFile_Type);procedureSet_Error (File :inFile_Type);functionStandard_InputreturnFile_Type;functionStandard_OutputreturnFile_Type;functionStandard_ErrorreturnFile_Type;functionCurrent_InputreturnFile_Type;functionCurrent_OutputreturnFile_Type;functionCurrent_ErrorreturnFile_Type;typeFile_AccessisaccessconstantFile_Type;functionStandard_InputreturnFile_Access;functionStandard_OutputreturnFile_Access;functionStandard_ErrorreturnFile_Access;functionCurrent_InputreturnFile_Access;functionCurrent_OutputreturnFile_Access;functionCurrent_ErrorreturnFile_Access; -- Buffer controlprocedureFlush (File :inoutFile_Type);procedureFlush; -- Specification of line and page lengthsprocedureSet_Line_Length (File :inFile_Type; To :inCount);procedureSet_Line_Length (To :inCount);procedureSet_Page_Length (File :inFile_Type; To :inCount);procedureSet_Page_Length (To :inCount);functionLine_Length (File :inFile_Type)returnCount;functionLine_LengthreturnCount;functionPage_Length (File :inFile_Type)returnCount;functionPage_LengthreturnCount; -- Column, Line, and Page ControlprocedureNew_Line (File :inFile_Type; Spacing :inPositive_Count := 1);procedureNew_Line (Spacing :inPositive_Count := 1);procedureSkip_Line (File :inFile_Type; Spacing :inPositive_Count := 1);procedureSkip_Line (Spacing :inPositive_Count := 1);functionEnd_Of_Line (File :inFile_Type)returnBoolean;functionEnd_Of_LinereturnBoolean;procedureNew_Page (File :inFile_Type);procedureNew_Page;procedureSkip_Page (File :inFile_Type);procedureSkip_Page;functionEnd_Of_Page (File :inFile_Type)returnBoolean;functionEnd_Of_PagereturnBoolean;functionEnd_Of_File (File :inFile_Type)returnBoolean;functionEnd_Of_FilereturnBoolean;procedureSet_Col (File :inFile_Type; To :inPositive_Count);procedureSet_Col (To :inPositive_Count);procedureSet_Line (File :inFile_Type; To :inPositive_Count);procedureSet_Line (To :inPositive_Count);functionCol (File :inFile_Type)returnPositive_Count;functionColreturnPositive_Count;functionLine (File :inFile_Type)returnPositive_Count;functionLinereturnPositive_Count;functionPage (File :inFile_Type)returnPositive_Count;functionPagereturnPositive_Count; -- Character Input-OutputprocedureGet (File :inFile_Type; Item :outCharacter);procedureGet (Item :outCharacter);procedurePut (File :inFile_Type; Item :inCharacter);procedurePut (Item :inCharacter);procedureLook_Ahead (File :inFile_Type; Item :outCharacter; End_Of_Line :outBoolean);procedureLook_Ahead (Item :outCharacter; End_Of_Line :outBoolean);procedureGet_Immediate (File :inFile_Type; Item :outCharacter);procedureGet_Immediate (Item :outCharacter);procedureGet_Immediate (File :inFile_Type; Item :outCharacter; Available :outBoolean);procedureGet_Immediate (Item :outCharacter; Available :outBoolean); -- String Input-OutputprocedureGet (File :inFile_Type; Item :outString);procedureGet (Item :outString);procedurePut (File :inFile_Type; Item :inString);procedurePut (Item :inString);procedureGet_Line (File :inFile_Type; Item :outString; Last :outNatural);procedureGet_Line (Item :outString; Last :outNatural);functionGet_Line(File :inFile_Type)returnString;functionGet_LinereturnString;procedurePut_Line (File :inFile_Type; Item :inString);procedurePut_Line (Item :inString); -- Generic packages for Input-Output of Integer TypesgenerictypeNumisrange<>;packageInteger_IOisDefault_Width : Field := Num'Width; Default_Base : Number_Base := 10;procedureGet (File :inFile_Type; Item :outNum; Width :inField := 0);procedureGet (Item :outNum; Width :inField := 0);procedurePut (File :inFile_Type; Item :inNum; Width :inField := Default_Width; Base :inNumber_Base := Default_Base);procedurePut (Item :inNum; Width :inField := Default_Width; Base :inNumber_Base := Default_Base);procedureGet (From :inString; Item :outNum; Last :outPositive);procedurePut (To :outString; Item :inNum; Base :inNumber_Base := Default_Base);endInteger_IO;generictypeNumismod<>;packageModular_IOisDefault_Width : Field := Num'Width; Default_Base : Number_Base := 10;procedureGet (File :inFile_Type; Item :outNum; Width :inField := 0);procedureGet (Item :outNum; Width :inField := 0);procedurePut (File :inFile_Type; Item :inNum; Width :inField := Default_Width; Base :inNumber_Base := Default_Base);procedurePut (Item :inNum; Width :inField := Default_Width; Base :inNumber_Base := Default_Base);procedureGet (From :inString; Item :outNum; Last :outPositive);procedurePut (To :outString; Item :inNum; Base :inNumber_Base := Default_Base);endModular_IO; -- Generic packages for Input-Output of Real TypesgenerictypeNumisdigits<>;packageFloat_IOisDefault_Fore : Field := 2; Default_Aft : Field := Num'Digits-1; Default_Exp : Field := 3;procedureGet (File :inFile_Type; Item :outNum; Width :inField := 0);procedureGet (Item :outNum; Width :inField := 0);procedurePut (File :inFile_Type; Item :inNum; Fore :inField := Default_Fore; Aft :inField := Default_Aft; Exp :inField := Default_Exp);procedurePut (Item :inNum; Fore :inField := Default_Fore; Aft :inField := Default_Aft; Exp :inField := Default_Exp);procedureGet (From :inString; Item :outNum; Last :outPositive);procedurePut (To :outString; Item :inNum; Aft :inField := Default_Aft; Exp :inField := Default_Exp);endFloat_IO;generictypeNumisdelta<>;packageFixed_IOisDefault_Fore : Field := Num'Fore; Default_Aft : Field := Num'Aft; Default_Exp : Field := 0;procedureGet (File :inFile_Type; Item :outNum; Width :inField := 0);procedureGet (Item :outNum; Width :inField := 0);procedurePut (File :inFile_Type; Item :inNum; Fore :inField := Default_Fore; Aft :inField := Default_Aft; Exp :inField := Default_Exp);procedurePut (Item :inNum; Fore :inField := Default_Fore; Aft :inField := Default_Aft; Exp :inField := Default_Exp);procedureGet (From :inString; Item :outNum; Last :outPositive);procedurePut (To :outString; Item :inNum; Aft :inField := Default_Aft; Exp :inField := Default_Exp);endFixed_IO;generictypeNumisdelta<>digits<>;packageDecimal_IOisDefault_Fore : Field := Num'Fore; Default_Aft : Field := Num'Aft; Default_Exp : Field := 0;procedureGet (File :inFile_Type; Item :outNum; Width :inField := 0);procedureGet (Item :outNum; Width :inField := 0);procedurePut (File :inFile_Type; Item :inNum; Fore :inField := Default_Fore; Aft :inField := Default_Aft; Exp :inField := Default_Exp);procedurePut (Item :inNum; Fore :inField := Default_Fore; Aft :inField := Default_Aft; Exp :inField := Default_Exp);procedureGet (From :inString; Item :outNum; Last :outPositive);procedurePut (To :outString; Item :inNum; Aft :inField := Default_Aft; Exp :inField := Default_Exp);endDecimal_IO; -- Generic package for Input-Output of Enumeration TypesgenerictypeEnumis(<>);packageEnumeration_IOisDefault_Width : Field := 0; Default_Setting : Type_Set := Upper_Case;procedureGet (File :inFile_Type; Item :outEnum);procedureGet (Item :outEnum);procedurePut (File :inFile_Type; Item :inEnum; Width :inField := Default_Width; Set :inType_Set := Default_Setting);procedurePut (Item :inEnum; Width :inField := Default_Width; Set :inType_Set := Default_Setting);procedureGet (From :inString; Item :outEnum; Last :outPositive);procedurePut (To :outString; Item :inEnum; Set :inType_Set := Default_Setting);endEnumeration_IO; -- Exceptions Status_Error :exceptionrenamesIO_Exceptions.Status_Error; Mode_Error :exceptionrenamesIO_Exceptions.Mode_Error; Name_Error :exceptionrenamesIO_Exceptions.Name_Error; Use_Error :exceptionrenamesIO_Exceptions.Use_Error; Device_Error :exceptionrenamesIO_Exceptions.Device_Error; End_Error :exceptionrenamesIO_Exceptions.End_Error; Data_Error :exceptionrenamesIO_Exceptions.Data_Error; Layout_Error :exceptionrenamesIO_Exceptions.Layout_Error;privatetypeFile_Typeislimitednullrecord;endAda.Text_IO;
See also
Wikibook
External examples
- Search for examples of
Ada.Text_IOin: Rosetta Code, GitHub or this Wikibook. - Search for any post related to
Ada.Text_IOin: Stack Overflow, comp.lang.ada or any Ada related page.
Ada Reference Manual
Ada 95
Ada 2005
Ada 2012
Ada Quality and Style Guide
Open-Source Implementations
FSF GNAT
- Specification: a-textio.ads
- Body: a-textio.adb
drake
- Specification: streams/a-textio.ads
- Body: streams/a-textio.adb