Is there an Ada function similar to GotoXY? [closed] - ada

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 2 years ago.
Improve this question
In Pascal there is a GotoXY function which positions the cursor at coordinates (X,Y) on the current window. Is there a similar function for Ada on Linux? I have found one for Win32 called NT_console, but nothing for Linux. More generally, is there any package which is similar to the crt unit on pascal? Thanks.

There’s ncurses (or, if instead you wanted a Windows solution, JEWL). I’ve never used either of them, though.

Not as such.
But here's a "terminal" package I put together when porting a Pascal program that did some interactive text editing, originally on a Windows CMD window ... actually, probably originally on DOS.
Incomplete, but maybe useful as a starting point. GotoXY is Set_Cursor here. Note the "atr" arguments on Clear_Scrn etc are ignored : this was good enough for my purpose : they could be removed (further simplifying the library) but were left for compatibility with the original project.
Works on a Debian Linux "Gnome Terminal" console but easily modified for other terminal types using escape sequences.
terminal.ads...
PACKAGE Terminal IS
TYPE WORD IS MOD 2**16;
-- returned by Read_Special which reads the keyboard. Parse these
-- if you need to interactively move round the screen, and get_cursor
-- and set_cursor accordingly. Or if between space and tilde,
-- call LOBYTE to extract the (Ada.Characters.Latin_1) character.
up_arrow : CONSTANT WORD := 16#5B41#;
dn_arrow : CONSTANT WORD := 16#5B42#;
lf_arrow : CONSTANT WORD := 16#5B44#;
rt_arrow : CONSTANT WORD := 16#5B43#;
pgup : CONSTANT WORD := 16#357E#;
pgdn : CONSTANT WORD := 16#367E#;
F2 : CONSTANT WORD := 16#4F51#;
F3 : CONSTANT WORD := 16#4F52#;
F4 : CONSTANT WORD := 16#4F53#;
ins : CONSTANT WORD := 16#327E#;
Esc : CONSTANT WORD := 16#001B#;
cr : CONSTANT WORD := 16#000D#;
lf : CONSTANT WORD := 16#000A#; -- accept cr or lf for Linux too
plus : CONSTANT WORD := 16#002B#;
minus : CONSTANT WORD := 16#002D#;
period : CONSTANT WORD := 16#002E#;
naught : CONSTANT WORD := 16#0030#;
nine : CONSTANT WORD := 16#0039#;
bcksp : CONSTANT WORD := 16#007F#; -- Gnome terminal "profile preferences" ...
-- backspace generates ASCII DEL (vs ctrl-H 0008)
space : CONSTANT WORD := 16#0020#; -- {first printable character}
tilda : CONSTANT WORD := 16#007E#; -- {last printable character}
FUNCTION LOBYTE(Data : WORD) RETURN CHARACTER;
PROCEDURE read_special(incode: OUT WORD); -- EXTERN;
-- {Reads special keyboard characters; LOBYTE(incode)= ASCII
-- HIBYTE(incode) = special code;}
PROCEDURE set_cursor(row, col: INTEGER); -- EXTERN;
-- {Sets screen cursor at line = row, column = col}
PROCEDURE get_cursor(row, col: OUT INTEGER); -- EXTERN;
-- {Gets current cursor position: line = row, column = col}
PROCEDURE backspace;
PROCEDURE clear_scrn(atr: INTEGER); -- EXTERN;
-- {Clears active display screen, sets display attribute}
PROCEDURE clear_ln(row, atr: INTEGER); -- EXTERN;
-- {Clears single line row on active display screen, sets display attribute;
PROCEDURE scrlup_scrn(topln, botln, atr: INTEGER); -- EXTERN;
PROCEDURE scrldn_scrn(topln, botln, atr: INTEGER); -- EXTERN;
-- {Scroll active display screen up or down one line in window defined by
-- topln and botln; sets display attribute of blank line; }
END Terminal;
terminal.adb
WITH Ada.Unchecked_Conversion;
WITH Ada.Text_IO; USE Ada.Text_IO;
WITH Ada.Integer_Text_IO; USE Ada.Integer_Text_IO;
WITH Ada.Characters.Latin_1;
PACKAGE BODY Terminal IS
FUNCTION LOBYTE(Data : WORD) RETURN CHARACTER IS
TYPE BYTE IS MOD 2**8;
FUNCTION Byte_To_Char IS NEW Ada.Unchecked_Conversion(BYTE,CHARACTER);
Temp : BYTE := BYTE(Data MOD 2**8);
BEGIN
RETURN Byte_To_Char(Temp);
END LOBYTE;
PROCEDURE read_special(incode: OUT WORD) IS
-- {Reads special keyboard characters; LOBYTE(incode)= ASCII
-- HIBYTE(incode) = special code;
temp1,temp2,tempx : CHARACTER := Ada.Characters.Latin_1.NUL;
avail : BOOLEAN;
BEGIN
get_immediate(Standard_Input, temp1); -- block until input
incode := Word(Character'pos(temp1));
get_immediate(Standard_Input, temp2, avail); -- check for sequences
IF avail THEN
LOOP
get_immediate(Standard_Input, tempx, avail);
EXIT WHEN NOT avail;
temp1 := temp2;
temp2 := tempx;
END LOOP; -- keep the last 2 characters of the sequence
incode := Word(Character'pos(temp1) * 256 + Character'pos(temp2));
END IF;
END read_special;
PROCEDURE set_cursor(row, col: INTEGER) IS
-- {Sets screen cursor at line = row, column = col; }
r0,r1,r2,c0,c1 : CHARACTER;
BEGIN
r0 := Character'val( Character'pos('0') + (row + 1) MOD 10);
r1 := Character'val( Character'pos('0') + ((row + 1) / 10) MOD 10);
r2 := Character'val( Character'pos('0') + ((row + 1) / 100) MOD 10);
c0 := Character'val( Character'pos('0') + (col + 1) MOD 10);
c1 := Character'val( Character'pos('0') + ((col + 1) / 10) MOD 10);
Put(Ada.Characters.Latin_1.ESC & '[' & r2 & r1 & r0 & ';' & c1 & c0 & 'H');
END set_cursor;
PROCEDURE get_cursor(row, col: OUT INTEGER) IS
-- {Gets current cursor position: line = row, column = col}
BEGIN
row := INTEGER(Ada.Text_IO.Line) - 1;
col := INTEGER(Ada.Text_IO.Col) - 1;
END get_cursor;
PROCEDURE backspace IS
BEGIN
Put(Ada.Characters.Latin_1.ESC & '[' & 'D'); -- Backspace
END backspace;
PROCEDURE clear_scrn(atr: INTEGER) IS
-- {Clears active display screen, sets display attribute}
-- row,col : INTEGER;
BEGIN
Put(Ada.Characters.Latin_1.ESC & '[' & '2' & 'J');
END clear_scrn;
PROCEDURE clear_ln(row, atr: INTEGER) IS
-- {Clears single line row on active display screen, sets display attribute;
BEGIN
set_cursor(row, 0);
Put(Ada.Characters.Latin_1.ESC & '[' & '2' & 'K');
END clear_ln;
PROCEDURE scrlup_scrn(topln, botln, atr: INTEGER) IS
-- {Scroll active display screen up or down one line in window defined by
-- topln and botln; sets display attribute of blank line}
BEGIN
Put(Ada.Characters.Latin_1.ESC & '[' & '1' & 'S');
END scrlup_scrn;
PROCEDURE scrldn_scrn(topln, botln, atr: INTEGER) IS
BEGIN
Put(Ada.Characters.Latin_1.ESC & '[' & '1' & 'T');
END scrldn_scrn;
END Terminal;
Terminal escape sequences documented here for example

Related

SigSegv when passing array element to a recursive function in a loop in Pascal

So in this program we ceate an array Tab1 with Random values in its 10 elements then we get the factorial of each Tab1 element and put it in Tab2, using two methods the iterative and the recursive one. When using the iterative function Tab2 is filled with factorials with no problems but when I use the recursive function the program quits immediately. If you can help me understanding the problem in depth I would be so much appreciated...I read about segmentation fault on Wikipedia which said that it's because the program is trying to get to a memery location that it doesn't have the permission to enter but the problem is when I choose a special element from Tab1 for example Tab1[5] and pass it to factorielleRecursive in Calc2 it works just as fine, any thoughts?
Program recursive;
Type
T = array [1..10] of LongInt;
Var
Tab1, Tab2 : T;
num : integer;
Function FactorielleIterative(N : integer) : integer;
Var
F, i : integer;
Begin
F := 1;
for i:=1 to N Do
F := F*i;
FactorielleIterative := F;
End;
Function FactorielleRecursive(N : LongInt) : LongInt;
Begin
if (N=1) Then
FactorielleRecursive := 1
Else
FactorielleRecursive := N * FactorielleRecursive(N-1);
End;
Procedure Fill(var Tab : T);
Var
i : Integer;
Begin
Randomize;
For i:=1 to 10 Do
Begin
Tab[i] := Random(10);
End;
For i:=1 to 10 Do
Write('[', Tab[i], '] ');
End;
Procedure Calc1(Tab1 : T; var Tab2 : T);
Var
i : integer;
Begin
For i:=1 to 10 Do
Begin
Tab2[i] := FactorielleIterative(Tab1[i]);
End;
For i:=1 to 10 Do
Write('[', Tab2[i], '] ');
End;
Procedure Calc2(Tab : T; var Tab2 : T);
Var
i : integer;
Begin
For i:=1 to 10 Do
Begin
Tab2[i] := FactorielleRecursive(Tab[i]);
End;
For i:=1 to 10 Do
Write('[', Tab2[i], '] ');
End;
Begin
Write('Tab1 : ');
Writeln;
Fill(Tab1);
Writeln;
Writeln;
Write('Tab2 : Iterative method');
Writeln;
Calc1(Tab1, Tab2);
Writeln;
Writeln;
Write('Tab2 : Recursive method');
Writeln;
Calc2(Tab1, Tab2);
Readln;
End.
You are not taking in consideration what happens if the Tab[] array contains a zero value. This situation is possible since you call Random(10) which will return a value in the range 0 .. 9.
In Function FactorielleIterative() an argument of zero is treated as a '1' value (because the for loop is not executed).
In Function FactorielleRecursive() an argument of zero is treated as a '0' value, with the consequence of the recursive call FactorielleRecursive(N-1); leading to range overflow.
The solution is simple so I leave it to you to fix, in order not to spoil your homework.
My thoughts:
I could not reproduce this issue in my setup:
bash$ fpc so.pas && ./so
Free Pascal Compiler version 3.2.0+dfsg-12 [2021/01/25] for x86_64
Copyright (c) 1993-2020 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling so.pas
so.pas(6,1) Note: Local variable "num" not used
Linking so
76 lines compiled, 0.1 sec
1 note(s) issued
NOTE: unused variable should be removed.
Can you provide more details about your compiler and its options at compile time and your OS?
Tab1[5] is just a random value: it changes run by run. How did you use it for verification? Do you know what was its current value? I called FactorielleRecursive(10); from the main block and I could not experience any issue with that. Is this issue intermittent in your runtime environment?
Your iterative function get and returns only Integer. I think you should change the return type to LongInt as you did in recursive way. Here a runtime difference between the two version (with some overflow: see the negative value(s)):
Tab2 : Iterative method
[5040]
[720]
[2]
[1]
[720]
[5040]
[24]
[1]
[-25216] <<<<<<<<<<<<<<<<< Integer overflow
[24]
Tab2 : Recursive method
[5040]
[720]
[2]
[1]
[720]
[5040]
[24]
[1]
[40320]
[24]
Minor notes:
You can extract repetitive code parts into a procedure/function. In this case the for loops repeated 3 times to write out contents of Tab array.
You can merge Write and WriteLn into a single statement. For example WriteLn('Tab2 : Iterative method'); - it is a more compact form.

Using multidimensional array in Ada

In this code, I need help writing a multidimensional array with a range between 2020-01-01 to 2119-12-31.
My code works but as you see there are no arrays in it. How can I write this code with only arrays?
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
Procedure Date is
type date_type is record
Str : string (1..8);
Length : Natural := 0; end record;
A: date_type;
begin
loop
Put ("Enter a date between 2020-01-01 to 2119-12-31 : ");
Get_Line (A.Str, A.Length);
exit when A.Length = 8;
Put_Line ("Wrong input. Try again.");
end loop;
Put_Line (A.Str (1 .. 4) & "-" & A.Str (5 .. 6) & "-" & A.Str (7 .. 8));
end Date;
Perhaps, rather than a multi-dimensional array you should consider using a record such as
type Year_Number is range 1900..3000;
type Month_Number is range 1..12;
type Day_Number is range 1..31;
type Date_Rec is record
Year : Year_Number;
Month : Month_Number;
Day : Day_Number;
end record;
subtype Year_String is string (1..4);
subtype Month_String is string (1..2);
subtype Day_String is string (1..2);
function To_Date (Yr : Year_String; Mnth : Month_String; Dy : Day_String)
return Date_Rec is
Result : Date_Rec;
begin
Result.Year := Year_Number'Value (Yr);
Result.Month := Month_Number'Value (Mnth);
Result.Day := Day_Number'Value (Dy);
return Result;
end To_Date;
You can now pass around instances of Date_
Rec doing whatever you want with the date.
If you go this far then you might want to consider using the Time type described in Ada Language Reference Manual sections 9.6 and 9.6.1.
You haven't asked a reasonable question here because "I want to use arrays" is not a good reason to use an array.
"This problem can be best solved with an array ... but how do I deal with ... ?" would be a reasonable question, but you haven't stated a problem,let alone one that needs an array.
This is important because "using an array" is thinking in the solution domain, like "using a chisel". It's not the way to think about programming in Ada, (or IMO in any language).
Try thinking in the problem domain first : instead of "I want to use a chisel", I think "I want to recess this hinge so the door fits precisely" and a chisel is the neatest way of doing the job.
Then "How can I best validate a date?" would be one reasonable question, or "how can I store events that happen on each day for 100 years?"
The answer to the first question is probably in the Ada.Calendar package. Possibly the Value function in Ada.Calendar.Formatting, with an exception handler to catch incomprehensible strings and make the user try again.
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Calendar;
with Ada.Calendar.Formatting;
procedure date is
Date : Ada.Calendar.Time;
Done : Boolean;
begin
loop
Put ("Enter a date between 2020-01-01 to 2119-12-31 : ");
Done := TRUE;
declare
A : String := Get_Line & " 12:00:00";
begin
Date := Ada.Calendar.Formatting.Value(A); -- validate it's a date
Done := Ada.Calendar.Year(Date) >= 2020
and Ada.Calendar.Year(Date) < 2120; -- validate correct range
exception
when Constraint_Error => Done := False; -- Formatting.Value failed
end;
exit when Done;
Put("Try Again : ");
end loop;
end date;
The answer to the second is probably a 1-dimensional array indexed by Day_Count from Ada.Calendar.Arithmetic but let's use the wrong tool : a 3D array indexed by your range of years, Month_Number and Day_Number from the Ada.Calendar base package.
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Calendar; use Ada.Calendar;
with Ada.Calendar.Formatting;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
procedure date is
Date : Ada.Calendar.Time;
Done : Boolean := TRUE;
Event_Array : array(2020 .. 2119,
Ada.Calendar.Month_Number,
Ada.Calendar.Day_Number) of Unbounded_String;
begin
Event_Array := (others => (others => (others => Null_Unbounded_String)));
Event_Array(2020,11,3) := To_Unbounded_String("nothing much");
loop
Put ("Enter a date between 2020-01-01 to 2119-12-31 : ");
Done := TRUE;
declare
A : String := Get_Line & " 12:00:00";
begin
Date := Ada.Calendar.Formatting.Value(A);
Done := Ada.Calendar.Year(Date) >= 2020
and Ada.Calendar.Year(Date) < 2120;
exception
when Constraint_Error => Done := False;
end;
exit when Done;
Put("Try Again : ");
end loop;
Put_Line("Today " & Ada.Calendar.Formatting.Image(Date) & " : " &
To_String(Event_Array(Year(Date), Month(Date), Day(Date))) & " happened");
end date;
Test with the string 2020-11-03

Calling "Ada.float_text_IO.get" from a package to read user input from the console

I want to use Ada.float_text_IO.Get , in a packagefile created : (.adb)&(.ads) from a mainfile to read user input from the console using the procedure:
procedure Get(Item : out Num; Width : in Field := 0);
There is no example anywhere . Help :)
Here is a complete working example which includes a package specification (floatget.ads) and body (floatget.adb) and a separate program (mainfile.adb) to call the Read_Floats_From_Console function in the FloatGet package.
The Ada 95 RM section A.10.9 Input-Output for Real Types indicates Ada.Float_Text_IO.Get skips leading whitespace and parses a float literal value of various formats from a file, optionally if you use the form without the File : in File_Type; argument then Get will read from the console.
Contents of floatget.ads package specification:
-- floatget.ads
--
-- FloatGet package specification defining procedure to read floats
-- from console
package FloatGet is
procedure Read_Floats_From_Console;
end FloatGet;
Contents of floatget.adb package body:
-- floatget.adb
--
-- FloatGet package body using Ada.Float_Text_IO.Get to read floats
-- from console
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Float_Text_IO;
package body FloatGet is
procedure Read_Floats_From_Console is
Val : Float;
Sum : Float := 0.0;
N : Integer := 0;
begin
Put_Line("Enter float values, one per line. Press CTRL-D when done.");
Read_Loop:
loop
exit Read_Loop when End_Of_File;
begin
Ada.Float_Text_IO.Get (Val);
exception
when Data_Error =>
Put_Line ("ERROR: Invalid float format");
exit Read_Loop;
end;
Put ("Read value = ");
Ada.Float_Text_IO.Put (Val);
Put (", ");
Ada.Float_Text_IO.Put (Val, Fore => 3, Exp => 0);
Put (", ");
Ada.Float_Text_IO.Put (Val, Aft => 2, Exp => 0);
New_Line;
Sum := Sum + Val;
N := N + 1;
end loop Read_Loop;
Put_Line ("Number of values = " & Integer'Image(N));
Put ("Sum of values = ");
Ada.Float_Text_IO.Put (Sum, Exp => 0);
New_Line;
end Read_Floats_From_Console;
end FloatGet;
Contents of mainfile.adb:
-- mainfile.adb
--
-- Main program calls FloatGet.Read_Floats_From_Console
--
-- Compilation: gnatmake floatget mainfile
--
-- Usage: ./mainfile
--
with FloatGet;
procedure MainFile is
begin
FloatGet.Read_Floats_From_Console;
end MainFile;
How to compile it... (tested with gnat 4.8.4, 4.9.3, 5.2.0 on Ubuntu 14.04)
$ gnatmake floatget mainfile
Sample run illustrating several valid float values...
$ ./mainfile
Enter float values, one per line. Press CTRL-D when done.
1
Read value = 1.00000E+00, 1.00000, 1.00
-1
Read value = -1.00000E+00, -1.00000, -1.00
42
Read value = 4.20000E+01, 42.00000, 42.00
-42
Read value = -4.20000E+01, -42.00000, -42.00
.3
Read value = 3.00000E-01, 0.30000, 0.30
-.3
Read value = -3.00000E-01, -0.30000, -0.30
2.0e3
Read value = 2.00000E+03, 2000.00000, 2000.00
-2.0e3
Read value = -2.00000E+03, -2000.00000, -2000.00
-16#1C.#e-1
Read value = -1.75000E+00, -1.75000, -1.75
2#.11#e6
Read value = 4.80000E+01, 48.00000, 48.00
... Press CTRL-D here ...
Number of values = 10
Sum of values = 46.25000
This example doesn't rely upon anything gnat-specific so should work with any Ada 95 compiler although I have no way to test with other compilers besides gnat presently.
EDIT Simplified to only read from console instead per OP's request.
There are two alternatives: wrap the procedure or rename it.
with Ada.Text_IO;
with Ada.Float_Text_IO;
procedure Main is
package My_Float_Text_IO is
procedure Get_1 (Item : out Float; Width : Ada.Text_IO.Field := 0);
procedure Get_2 (Item : out Float; Width : Ada.Text_IO.Field := 0) renames Ada.Float_Text_IO.Get;
end;
package body My_Float_Text_IO is
procedure Get_1 (Item : out Float; Width : Ada.Text_IO.Field := 0) is
begin
Ada.Float_Text_IO.Get (Item, Width);
end;
end;
F : Float;
begin
My_Float_Text_IO.Get_1 (F);
My_Float_Text_IO.Get_2 (F);
end;
Put specification code into .ads files and body cody (implementation code) into .adb files.
You can also just put one procedure or function in .ads and .adb file without package. You can also have a specification package without body package.

raised CONSTRAINT_ERROR : josephus.adb:50 index check failed

I'm trying to run this code, but something is going wrong with the line:
Soldiers (Number_Of_Soldiers) := Soldier_Type'(Name=>new String'(Line(1..Length)), Alive=>True);
Can someone help me, please?
Thank you so much!
--Josephus Problem
with Ada.Text_IO,Ada.Integer_Text_IO;
use Ada;
procedure Josephus is
type String_Pointer is access String;
type Soldier_Type is record
Name : String_Pointer;
Alive : Boolean;
end record;
Max_Number_Of_Soldiers: constant := 10;
Number_Of_Soldiers : Integer range 0..Max_Number_Of_Soldiers := 0;
-- start with 0 to facilitate modular arithmetic
Soldiers: array (0..Max_Number_Of_Soldiers-1) of Soldier_Type;
procedure Next (Index: in out Integer; Interval: Positive) is
begin
for I in 1..Interval loop
loop
Index := (Index + 1) mod Number_Of_Soldiers;
exit when Soldiers(Index).Alive;
end loop;
end loop;
end Next;
Interval : Integer;
Man : Integer := Soldiers'First;
begin
-- get interval from the standard input
Integer_Text_IO.Get (Interval);
Text_IO.Skip_Line;
Text_IO.Put ("Skip every ");
Integer_Text_IO.Put (Interval, Width=>1);
Text_IO.Put_Line (" soldiers.");
-- get names (one per line) from the standard input
declare
Line: String (1..10);
Length: Integer;
begin
while not (Text_IO.End_Of_File) loop
Text_IO.Get_Line (Line, Length);
Soldiers (Number_Of_Soldiers) := Soldier_Type'(Name=>new String'(Line(1..Length)), Alive=>True);
Number_Of_Soldiers := Number_Of_Soldiers + 1;
end loop;
end;
for I in 1..Number_Of_Soldiers-1 loop
Soldiers(Man).Alive := False;
Text_IO.Put (Soldiers(Man).Name.all);
Text_IO.Put_Line (" commits suicide.");
Next (Man, Interval);
end loop;
Text_IO.Put (Soldiers(Man).Name.all);
Text_IO.Put_Line (" is the last.");
end Josephus;
I think your problem is with the line
Max_Number_Of_Soldiers: constant := 10;
Obviously the number specified needs to be more than the maximum possible number of entries in your input!
The problem of unbounded input data sets is one reason to look at using Ada.Containers.Vectors instead of arrays.

Function reading from standard input without any "in" parameters

Perhaps this is simple, and I am just missing some basic information, but I can't seem to find the answer anywhere.
I'm writing a Get_Word function for class, here is the relevant section of the spec file my prof wrote:
function Get_Word return Ustring;
-- return a space-separated word from standard input
procedure Fill_Word_List(Wl : in out Ustring_Vector);
-- read a text file from standard in and add all
-- space-separated words to the word list wl
I've written the Get_Word function, and am trying to test it out with this code:
with Ada.Text_IO; use Ada.Text_Io;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure ngramtest is
Name : String(1..80);
File : File_Type;
Size : Natural;
function Get_Word return String is
-- I'm using a strings instead of Unbounded_Strings for testing purposes.
Word : String(1..80) := (others => ' ');
Char : Character;
File : File_Type;
Eol : Boolean;
I : Integer := 1;
begin
--this code below, when uncommented reveals whether or not the file is open.
--if Is_Open(File) then
-- Word := (1..80 => 'y');
--else
-- Word := (1..80 => 'n');
--end if;
loop
Look_Ahead(File, Char, Eol);
if Eol then
exit;
elsif Char = ' ' then
exit;
else
Get (File, Char);
Word(I) := Char;
I := I + 1;
end if;
end loop;
return Word(1..Word'Last);
end Get_Word;
begin
Put ("Enter filename: ");
Get_Line (Name, Size);
Open (File, Mode => In_File, Name => Name(1..Size));
Put (Get_Word);
Close(File);
end ngramtest;
It compiles, but at runtime I get an exception telling me that the file isn't open, and the commented out section returns "nnnnnn..." meaning that the file is not open within the function.
My question is how am I to read from standard input if i'm not allowed to use in parameters in my function? Without them the function won't be able to access files.
Essentially, how can I "Get_Word"?
Sorry if this is simple, but I'm completely lost.
You need to set your "File" variable to standard input:
File : File_Type := Ada.Text_IO.Standard_Input;

Resources