You have many factors to consider when defining the record to contain your information.
It will be useful to create a named subtype of float, or a named floating point type so that the I/O routines can check the input values for the price component.
Fields of type String must be constrained to a predefined size. This means that all "company" strings must be the same size, and all "model" strings must be the same size, although model strings may be a different length than company strings. If the names of companies and/or models may vary then you should consider using either bounded strings (Ada Language Reference Manual section A.4.4) or unbounded strings (Ada Language Reference Manual section A.4.5).
If the strings of the input file are fixed in size you can use Ada.Text_IO.Text_Streams (Ada Language Reference Manual section A.12.2) to read each field of the record. If the strings can be different sizes then you will need to read and parse each field manually using Ada.Text_IO.
-- Read record data from a file
with Ada.Text_Io; use Ada.Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
procedure read_record is
type Prices is delta 0.01 digits 7 range 0.0..99999.99;
type Auto_Inventory is record
Price : Prices := 0.0;
Company : Unbounded_String := Null_Unbounded_String;
Model : Unbounded_String := Null_Unbounded_String;
end record;
package AI_IO is new Ada.Text_IO.Decimal_IO(Prices);
use AI_IO;
Inventory_Item : Auto_Inventory;
The_File : File_Type;
File_Name : String := "inventory.txt";
Inpt_Str : String(1..1024);
Length : Natural;
Start, Finis : Positive;
begin
Open(File => The_File,
Mode => In_File,
Name => File_Name);
Get(File => The_File,
Item => Inventory_Item.Price);
Get_Line(File => The_File,
Item => Inpt_Str,
Last => Length);
Close(The_File);
Start := Index_Non_Blank(Source => Inpt_Str(1..Length));
Finis := Start;
while Finis < Length and then Inpt_Str(Finis) /= ' ' loop
Finis := Finis + 1;
end loop;
Inventory_Item.Company := To_Unbounded_String(Inpt_Str(Start..Finis));
Start := Index_Non_Blank(Inpt_Str(Finis + 1..Length));
Inventory_Item.Model := To_Unbounded_String(Inpt_Str(Start..Length));
Put_Line("Price: " & Prices'Image(Inventory_Item.Price));
Put_Line("Company: " & To_String(Inventory_Item.Company));
Put_Line("Model: " & To_String(Inventory_Item.Model));
end read_record;
If you want to read a file containing many records you need to collect the information in some kind of container. The following example uses a Vector from the generic package Ada.Containers.Vectors.
-- Auto Inventory Package specification
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Vectors;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
package Auto_Inventory is
type Prices is delta 0.01 digits 7 range 0.0..99999.99;
type Automobile is tagged private;
procedure Print(Item : Automobile);
function Set return Automobile;
function Get_Price(Item : Automobile) return Prices;
function Get_Company(Item : Automobile) return String;
function Get_Model(Item : Automobile) return String;
type Inventory is tagged private;
procedure Read(Item : out Inventory; File : File_Type) with
Pre => Mode(File) = In_File;
procedure Write(Item : in Inventory; File : File_type) with
Pre => Mode(File) = Out_File;
procedure Print(Item : Inventory);
private
type Automobile is tagged record
Price : Prices := 0.0;
Company : Unbounded_String := Null_Unbounded_String;
Model : Unbounded_String := Null_Unbounded_String;
end record;
package Auto_Vect is new
Ada.Containers.Vectors(Index_Type => Positive,
Element_Type => Automobile);
use Auto_Vect;
type Inventory is tagged record
List : Vector;
end record;
end Auto_Inventory;
The body for this package is:
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
package body Auto_Inventory is
package Prices_IO is new Ada.Text_IO.Decimal_IO(Prices);
use Prices_IO;
-----------
-- Print --
-----------
procedure Print (Item : Automobile) is
use Prices_Io;
begin
Put_Line("Price : " & Prices'Image(Item.Price));
Put_Line("Company: " & To_string(Item.Company));
Put_Line("Model : " & To_String(Item.Model));
New_Line;
end Print;
---------
-- Set --
---------
function Set return Automobile is
Temp : Automobile;
Inpt_Str : String(1..1024);
Length : Natural;
begin
Put("Enter the automobile price: ");
Get(Item => Temp.Price);
Put("Enter the automobile company: ");
Get_Line(Item => Inpt_Str, Last => Length);
Temp.Company := To_Unbounded_String(Inpt_Str(1..Length));
Put("Enter the automobile model: ");
Get_Line(Item => Inpt_Str, Last => Length);
Temp.Model := To_Unbounded_String(Inpt_Str(1..Length));
return Temp;
end Set;
---------------
-- Get_Price --
---------------
function Get_Price (Item : Automobile) return Prices is
begin
return Item.Price;
end Get_Price;
-----------------
-- Get_Company --
-----------------
function Get_Company (Item : Automobile) return String is
begin
return To_String(Item.Company);
end Get_Company;
---------------
-- Get_Model --
---------------
function Get_Model (Item : Automobile) return String is
begin
return To_String(Item.Model);
end Get_Model;
----------
-- Read --
----------
procedure Read (Item : out Inventory;
File : File_Type) is
Temp : Inventory;
Auto : Automobile;
Inpt_Str : String(1..1024);
Length : Natural;
Start, Finis : Positive;
begin
while not End_Of_File(File) loop
Get(File => File, Item => Auto.Price);
Get_Line(File => File, Item => Inpt_str, Last => Length);
Start := Index_Non_Blank(Inpt_Str(1..Length));
Finis := Start;
while Finis < Length and then Inpt_Str(Finis) /= ' ' loop
Finis := Finis + 1;
end loop;
Auto.Company := To_Unbounded_String(Inpt_Str(Start..Finis - 1));
Start := Index_Non_Blank(Inpt_Str(Finis..Length));
Auto.Model := To_Unbounded_String(Inpt_Str(Start..Length));
Temp.List.Append(Auto);
end loop;
Item := Temp;
end Read;
-----------
-- Write --
-----------
procedure Write (Item : in Inventory;
File : File_type) is
begin
for Element of Item.List loop
Put(File => File, Item => Prices'Image(Element.Price) &
" " & To_String(Element.Company) & " " &
To_String(Element.Model));
New_Line;
end loop;
end Write;
-----------
-- Print --
-----------
procedure Print (Item : Inventory) is
begin
for Element of Item.List loop
Element.Print;
end loop;
end Print;
end Auto_Inventory;
An example of a main procedure to exercise this package:
------------------------------------------------------------------
-- Read a file of many records --
------------------------------------------------------------------
with Auto_Inventory; use Auto_Inventory;
with Ada.Text_IO; use Ada.Text_IO;
procedure read_file is
The_Inventory : Inventory;
The_File : File_Type;
File_Name : String := "inventory.txt";
begin
Open(File => The_File,
Mode => In_File,
Name => File_Name);
The_Inventory.Read(The_File);
Close(The_File);
The_Inventory.Print;
end read_file;
An example input file for this program is:
22134.09 Kia Bernice
12201.15 Nissan Versa
22349.99 Chevrolet Cruse