This is a very instructive example. It took me quite a while to understand what was going on. But looking at the implementation of End_of_File it dawned on me.
In the code above the program only waits the first time at Get_Line. All other times it waits at End_Of_Line. End_Of_Line waits for input! According to the RM End_Of_Line examines the NEXT character of the input stream. To do so it reads from the input stream, i.e. if no char is available, End_Of_Line waits for input. The character it then gets from the input stream is examined for being an end-of-line (ASCII.LF). If it is, True is returned, if it is not, False. Then the character read is put back into to input stream (!) and the complete stream is then consumed by Get_Line.
Very very instructive!
Lesson learned (for me): do not use End_Of_Line without good thought and preferably not combined with Get_Line (Input, Last), i.e. with a constraint string.
Go To statement and EOF tests considered harmful.
EOF has semantics inconsistent with the behaviour of a huge amount of types of hardware and software protocols. The idea comes from UNIX and that alone should be enough for everybodyâŚ
I recommend just reading and reading until you hit the End_Of_File exception. (See the RM Example.)
There was an error in my commented output.
I corrected it starting with number 5.
Ada abstracts away how an end of line is implemented. (There was the Siemens BS 2000, which implemented lines in a totally different way - there was no LF or CR.) Therefore with Text_IO you cannot return the character LF, even if it exists in the file, function End_Of_Line is the replacement.
Here, LF is not got from the input stream and put back - Look_Ahead or something like this is used.
RobG9876, I tried your simple program. It does exactly as you have told. The problem is that a keyboard has never an exact number of characters. If in your program you only enter the characters 1 unto 9 the program is stil waiting for another characters. As also can be seen the very simple program does the same
pragma License(Unrestricted);
with Ada.Text_IO; use Ada.Text_IO;
procedure test_get_keyboard is
Line : string (1..10);
Last : natural;
begin
PUT("Input String = ");
Get_Line(Line, Last);
Put_Line("Ready = " & Line(1 .. Last));
end test_get_keyboard;
At 10 characters exactly the program runs correctly. At 9 it waits again.
Well, your test_get_keyboard terminates when 9 chars are entered and then return.
What the problem seems to be is that when there is a caller of test_get_keyboard and that caller uses End_Of_Line, then the program indeed waits because End_of_Line waits for input.
Hmm, I beg to differ, at least on Windows. When examining the code of End_Of_Line, as can be found in the a-textio.adb file the code for End_Of_Line is:
-----------------
-- End_Of_Line --
-----------------
function End_Of_Line (File : File_Type) return Boolean is
ch : int;
begin
FIO.Check_Read_Status (AP (File));
if File.Before_Upper_Half_Character then
return False;
elsif File.Before_LM then
return True;
else
ch := Getc (File);
if ch = EOF then
return True;
else
Ungetc (ch, File);
return (ch = LM);
end if;
end if;
end End_Of_Line;
As you can see, there is a call to Getc and a call to Ungetc.
When looking at the code for Look_Ahead in the same source there are also calls to Getc and Ungetc.
Maybe on Unix / Linux this is different ?
Ah, IC, Look_Ahead has similar code.
I very much doubt that you really ran this piece of code.
I just tried it, and here are some of my outputs
attempt 1
Input String = 123456789
Ready = 123456789
attempt 2
Input String = 1
Ready = 1
attempt 3
Input String = 12345678901234567890
Ready = 1234567890
Get_Line seems to work the way others have described, and as I have experienced on both Linux and Windows.
Why you donât use Ada.Text_IO.Integer_IO?
A need a keyboard input function that is able to handle strings, integers, doubles etc.
Starting with a string function it is easy to create functions for other types.
In some descriptions is suggested that different operating have other ways to react on various types of keyboards. I need to have a keyboard routine That is able to read any length of string on any keyboard and on any operating system.
âŚI think perhaps you are âmissing the forest for the treesâ.
Some of the things youâre posting tend to point to a mental model that is different than what people are pointing out the language says, others seem to indicate that you donât know what youâre trying to do. (The squirreliness in posting your full/minimalized reproducer.)
My unsolicited advice is for you to step away from the keyboard, pull out a sheet of paper and physically draw out a diagram of your system. Use a bulleted list for your high-level goals, if need be. â Iâm not saying this to be dismissive, but that there are a significant number of programmers that âthink fastâ and then run with that idea, pouring minutes/hours/days of effort in, when a few minutes of âthink slowâ would save them 10x the time.
Stop.
Think about what youâre doing, at the high-level.
Ask yourself âwhyâ you need this functionality; ask yourself âhowâ you would test this functionality; ask yourself if this is really what you need.
Then, consider alternatives, eg that Stream is a generalized Input/Output construct: thus if you use Stream as your base for input, then crafting a âKeyboard -> Streamâ connector solves your problem. Consider other alternatives. Then consider the impact of these on your underlying design.
I say this because your âI need to have a keyboard routine That is able to read any length of string on any keyboard and on any operating system.â is fundamentally more work that you are thinking. â In my old OS Dev work, I made [the beginnings] of an OS written entirely in Turbo Pascal, save a â2-lineâ machine-code insertion which handled Gate A20, which dealt with the keyboard-controller on x86 machines, something that is not guaranteed to even exist on other architectures like, say, M68k-boards.
Text_IO is not about keyboards at all! It is about some kind of input stream with specific advanced semantic over usual âpipeâ. Standard library provides packages/subprograms to get string of some length, line, integer/modular/float/fixed number, enumeration literals. It is very helpful to write âbatchâ application, but almost useless for interactive applications.
If you need to create interactive application you should not use Text_IO at all. Most probably you need to create own implementation(s) on top of OS API.
My first contact with ADA was with they now call ADA 83. I think it is the name now. The reason ADA was created then was to create a language that could be used independent of operating system and hardware. the main reason was that the same program was to be used on every combination of OS and hardware without reprogramming if you changed hardware or operating system. Part of my department was going to use it.
Now the following: I got a little bit further Here the listing I now got:
procedure test_get_keyboard is
In_Line : string (1 .. 100);
Last : natural;
char1 : character;
char2 : character;
chr1 : integer;
chr2 : integer;
begin
PUT("Input String = ");
Get_Line(In_Line, Last);
Put_Line("Character = " & In_Line(Last));
Put_Line("Character + 1 = " & In_Line(Last + 1));
Put_Line("Character + 2 = " & In_Line(Last + 2));
Put_Line("Last = " & naturalâimage(Last));
Put_Line("Output = " & In_Line(1 .. Last));
char1 := In_line(Last + 1);
char2 := In_line(Last + 2);
chr1 := characterâPos(char1);
chr2 := characterâPos(char2);
Put_Line("Next Character ASCII value = " & integerâimage(chr1));
Put_Line("Second Next Character ASCII value = " & integerâimage(chr2));
end test_get_keyboard;
The result was:
Input String = fghjkiuytrewqmn><
Character = <
Character + 1 = E
Character + 2 = ð
Last = 17
Output = fghjkiuytrewqmn><
Next Character ASCII value = 69
Second Next Character ASCII value = 240
After the input I had to enter two extra times before the other put_Lineâs were executed.
The characters after the string changed every time
As expected.
Youâre using a buffer when you read in, say, the 5 characters of "Hello", none of the other characters in the buffer are changed, thus grabbing the ânextâ character will yield the garbage that was in the buffer from before.
This is to say, upon reading in "Hello", the value of In_Line(Last) should be 'o', and anything thereafter is âundefinedâ. â As people have told you upthread, this is the behavior that is defined, and expected. â But, even more spectacularly, this behavior is as it must be given your own statement of âThe reason ADA was created then was to create a language that could be used independent of operating system and hardware.â precisely because non-ASCII machines obviously would not have the same control-character bitwise layout: for what would LF be on a computer that had no such character?
That means that the program you are showing us is NOT the program you used to test. After adding âwith Ada.Text_Io; use Ada.Text_Io;â and the non-Ascii quotes are changed to valid chars (!) in the presented program, when it is compiled then it will only need one (1) Enter from the keyboard to complete. Again, please do NOT present incomplete examples
At this moment after very much trying and error i got:
pragma License(Unrestricted);
with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO; use Ada.Text_IO;
procedure test_get_keyboard is
In_Line : string := Get_Line;
begin
Put_Line("Input = ");
Put_line("Between = " & In_Line );
Put_Line("Length = " & " Length of In_Line" & natural'image(In_Line'Length));
Put_Line("Output = " & In_Line);
end test_get_keyboard;
Output:
D:\ada\project\Test_Get_Keyboard\test_get_keyboard.exe
Input =
Between = 1234567890
Length = Length of In_Line 10
Output = 1234567890
[2026-03-30 16:19:26] process terminated successfully, elapsed time: 14.38s
After Input of 1234567890 I had to give two CRLF's to get the rest of output. I hope. the last problem