The Ada Program: sort_names.adb
1 -- sort_names.adb: A main program using generic bounded strings package
2
3 with Ada.Text_IO, Bounded_Strings;
4 use Ada;
5 procedure Sort_Names is
6
7 -- Program 5-2 by Dale, Lilly, & McCormick
8
9 -- This program reads names from the keyboard and displays them in
10 -- alphabetical order. Names may be entered one per line in one of two forms:
11 --
12 -- First_Name Last_Name or Last_Name, First_Name
13 --
14 -- The comma is required in the second form.
15 -- End of input is indicated with a null name.
16 --
17 -- Assumptions: 1. There are no more than 20 names.
18 -- 2. All input lines contain less than 30 characters
19 -- 3. There is only one blank between the first and
20 -- last names; and no leading, or trailing blanks.
21
22 Max_Name_Length : constant := 30; -- Maximum characters in any name
23 Max_Names : constant := 20; -- Maximum number of names
24
25 -- Instantiate a bounded-length string package
26 package String30 is new Bounded_Strings (Max_Length => Max_Name_Length);
27 use String30; -- Make operations in String30 directly visible
28
29 -- Array type for holding all the names
30 type Index_Type is range 0..Max_Names;
31 subtype Index_Range is Index_Type range 1..Max_Names;
32 type Name_Array is array (Index_Range range <>) of String30.Bounded_String;
33
34 -- Variables for main program
35 Name : String30.Bounded_String; -- One name
36 Name_List : Name_Array (Index_Range); -- List of names entered by the user
37 Num_Names : Index_Type; -- Number of names entered
38
39 -- An unordered list is taken as input. The same list
40 -- with the components in ascending order is returned
41 procedure Selection_Sort (List : in out Name_Array) is
42 Name : String30.Bounded_String; -- Temporary variable for swapping
43 Min_Index : Index_Type; -- Index of minimum so far
44 begin
45 for Pass_Count in List'First .. List'Last - 1 loop
46 -- Find index of smallest item in List(Pass_Count)..List(List'Last)
47 Min_Index := Pass_Count;
48 for Place_Count in Pass_Count + 1 .. List'Last loop
49 -- Compare names with String30."<"
50 if List(Place_Count) < List(Min_Index) then
51 Min_Index := Place_Count;
52 end if;
53 end loop;
54 -- Swap List(Min_Index) and List(Pass_Count)
55 Name := List(Min_Index);
56 List(Min_Index) := List(Pass_Count);
57 List(Pass_Count) := Name;
58 end loop;
59 end Selection_Sort;
60
61
62 -- We assume the given name is of the form "First Last" with
63 -- exactly one blank between the names, or of the form "Last, First".
64 -- Names of the first form are converted to the latter.
65
66 procedure Last_Name_First (Name : in out String30.Bounded_String) is
67 Blank : constant Bounded_String := To_Bounded_String (" ");
68 Position : Natural; -- Position result of string search
69 begin
70 -- Determine the position of the blank
71 Position := Index (Source => Name, Pattern => Blank);
72 -- Is the first name first (no comma indicates it is)?
73 if Element (Name, Position-1) /= ',' then
74 -- Put the last name first (separated by a comma and a blank)
75 Name := Slice (Name, Position+1, Length(Name))-- The last name
76 & ", " -- A comma and blank
77 & Slice (Name, 1, Position-1); -- The first name
78 end if;
79 end Last_Name_First;
80
81 begin
82
83 -- Get all the names
84 Num_Names := 0;
85 Input_Loop: -- Each iteration, one name is processed
86 loop
87 Text_IO.Put_Line ("Enter a name (blank name to end)");
88 String30.Get_Line (Item => Name);
89 -- Is this a null name?
90 exit Input_Loop when Length (Name) = 0;
91 -- Make sure the last name comes before the first name
92 Last_Name_First (Name);
93 -- Put the name into the list
94 Num_Names := Num_Names + 1;
95 Name_List (Num_Names) := Name;
96 end loop Input_Loop;
97
98 -- Sort the names
99 Selection_Sort (List => Name_List (1..Num_Names));
100
101 -- Display the sorted names
102 for Index in 1..Num_Names loop
103 String30.Put (Item => Name_List (Index));
104 Text_IO.New_Line;
105 end loop;
106
107 end Sort_Names;