with ada.text_io; use ada.text_io; with ada.integer_text_io; use ada.integer_text_io; -- When using gnat, requires -gnato option to enable overflow checks procedure table5 is type Alignment is (left, center, right); package AlignmentIO is new Ada.text_io.enumeration_IO(Alignment); use AlignmentIO; ColumnWidth: constant Integer := 11; -------------------------------------------------------- -- Input one integer -------------------------------------------------------- procedure getOneItem( item: out Integer; prompt: String; lowerBound: Integer; errorMsg: String) is begin loop begin put(prompt); get(item); exit when item > lowerBound; put_line(errorMsg); exception when Data_Error => new_line; put_line("Must enter a valid integer value."); -- Discard anything left on input line skip_line; when others => new_line; put_line("Unknown exception occurred."); put_line("Bailing out!"); exit; end; end loop; end getOneItem; -------------------------------------------------------- -- Input the alignment -------------------------------------------------------- procedure getAlignment(prompt: string; align: out Alignment) is begin loop begin put(prompt); get(align); exit; exception when Data_Error => put_Line("Invalid alignment"); end; end loop; end getAlignment; -------------------------------------------------------- -- Input all the data -------------------------------------------------------- procedure getData(sI, fI, sP, fP: out Integer; align: out Alignment) is begin getAlignment("Enter alignment: ", align); getOneItem(sI, "Enter starting integer: ", -1, "Integer must be non-negative"); getOneItem(fI, "Enter ending integer: ", sI, "Ending integer must be larger than starting"); getOneItem(sP, "Enter starting power: ", -1, "Power must be non-negative"); getOneItem(fP, "Enter ending power: ", sP, "Ending power must be larger than starting"); end getData; -------------------------------------------------------- -- Output the table's header rows -- Precondition: sPow, fPow in 1 .. 99 -------------------------------------------------------- procedure putHeader(sPow, fPow: Integer; align: Alignment) is begin -- Start with some white space new_line; -- First column if align = left then put("I "); for i in sPow .. fPow loop put("I**"); put(i, 1); if i in 1 .. 9 then put(" "); else put(" "); end if; end loop; elsif align = center then put(" I "); for i in sPow .. fPow loop put(" I**"); put(i, 1); if i in 1 .. 9 then put(" "); else put(" "); end if; end loop; else -- must be right put(" I"); for i in sPow .. fPow loop if i in 1 .. 9 then put(" I**"); else put(" I**"); end if; put(i, 1); end loop; end if; -- Columns for powers new_line; -- Add one to fPow to account for column for I for i in sPow .. fPow + 1 loop put("-----------"); end loop; new_line; end putHeader; -------------------------------------------------------- -- Return the number of digits in i -------------------------------------------------------- function length(i: Integer) return Natural is begin -- A quick and dirty method: -- Subtract 1 because of the leading space return Integer'Image(i)'length - 1; end length; -------------------------------------------------------- -- New procedure -- Output v, aligned left, right, or center in ColumnWidth wide column -------------------------------------------------------- procedure put(v: Integer; align: Alignment) is lenV: constant Integer := length(v); blanks: String(1..10) := (others => ' '); numLeft, numRight: Natural; begin --put(v); put(lenV); case align is when left => put(v, 1); put(blanks(1 .. ColumnWidth - lenV)); when right => put(blanks(1 .. ColumnWidth - lenV)); put(v, 1); when center => numLeft := (ColumnWidth - lenV) / 2; numRight := ColumnWidth - lenV - numLeft; put(blanks(1 .. numLeft)); put(v, 1); put(blanks(1 .. numRight)); end case; end put; -------------------------------------------------------- -- Output rows of the table from sInt to fInt, -- with powers from sPow to fPow, -- aligned as specified -------------------------------------------------------- procedure putRows(sInt, fInt, sPow, fPow: Integer; align: Alignment) is tempInt: Integer; overflow: Boolean; begin for i in sInt .. fInt loop put(i, align); for j in sPow .. fPow loop overflow := false; begin tempInt := i ** j; exception when Constraint_Error => overflow := true; end; if not overflow then put(tempInt, align); -- MOdified statement else put(" ********"); end if; end loop; new_line; end loop; end putRows; -- Start and finish values for the rows startI, finishI: Integer; -- Start and finish values for the columns startPower, finishPower: Integer; -- Start and finish values for the columns align: Alignment; begin getData(StartI, finishI, startPower, finishPower, align); putHeader(startPower, finishPower, align); putRows(startI, finishI, startPower, finishPower, align); end table5;