A.10.7 Input-Output of Characters and Strings
For an item of type Character the following procedures are provided: procedure Get(File : in File_Type; Item : out Character);
procedure Get(Item : out Character);
After skipping any line terminators and any page terminators, reads the next character from the specified input file and returns the value of this character
in the out parameter Item.
The exception End_Error is propagated if an attempt is made to skip a file terminator.
Hello,
I'm reading a text file with Get character from Text_IO with a while
loop controlled by End_Of_File.
% cat test_20230922_get_char.adb
with Ada.Text_IO; use Ada.Text_IO;
procedure test_20230922_get_char is
  procedure Get is
     F : File_Type;
     Ch : Character;
  begin
     Open (F, In_File, "test_20230922_get_char.adb");
     while not End_Of_File(F) loop
        Get (F, Ch);
        Put (Ch);
     end loop;
     Close (F);
     Put_Line ("File read with get.");
  end;
begin
Get;
end;
All will be well, unfortunately not!
Despite the End_Of_File, I got an END_ERROR exception when there are
several trailing new lines at the end of the text:
% test_20230922_get_char
with Ada.Text_IO; use Ada.Text_IO;procedure test_20230922_get_char is procedure Get is     F : File_Type;     Ch : Character;  begin Open
(F, In_File, "test_20230922_get_char.adb");     while not End_Of_File(F) loop        Get (F, Ch);        Put (Ch);     end
loop;Â Â Â Â Â Close (F);Â Â Â Â Â Put_Line ("File read with get."); end;beginGet;end;
Execution of ../bin/test_20230922_get_char terminated by unhandled
exception
raised ADA.IO_EXCEPTIONS.END_ERROR : a-textio.adb:517
The code is compiled with GNAT, does it comply with the standard?
A.10.7 Input-Output of Characters and Strings
For an item of type Character the following procedures are provided: procedure Get(File : in File_Type; Item : out Character);
procedure Get(Item : out Character);
After skipping any line terminators and any page terminators, reads the
next character from the specified input file and returns the value of
this character in the out parameter Item.
The exception End_Error is propagated if an attempt is made to skip a
file terminator.
This seems to be the case, then how to avoid the exception?
On 2023-09-22 21:30, Blady wrote:
A.10.7 Input-Output of Characters and Strings
For an item of type Character the following procedures are provided:
procedure Get(File : in File_Type; Item : out Character);
procedure Get(Item : out Character);
After skipping any line terminators and any page terminators, reads
the next character from the specified input file and returns the value
of this character in the out parameter Item.
The exception End_Error is propagated if an attempt is made to skip a
file terminator.
As you have quoted, Get (Character) skips line terminators. End_Of_File returns True if there is a single line terminator before the file
terminator, but False if there are multiple line terminators before the
file terminator. So you either have to explicitly skip line terminators,
or handle End_Error.
Le 22/09/2023 à 22:05, Jeffrey R.Carter a écrit :
On 2023-09-22 21:30, Blady wrote:And this works only if the input file is "well formed", i.e. if it has
A.10.7 Input-Output of Characters and Strings
For an item of type Character the following procedures are provided:
procedure Get(File : in File_Type; Item : out Character);
procedure Get(Item : out Character);
After skipping any line terminators and any page terminators, reads
the next character from the specified input file and returns the
value of this character in the out parameter Item.
The exception End_Error is propagated if an attempt is made to skip a
file terminator.
As you have quoted, Get (Character) skips line terminators.
End_Of_File returns True if there is a single line terminator before
the file terminator, but False if there are multiple line terminators
before the file terminator. So you either have to explicitly skip line
terminators, or handle End_Error.
line terminators as the compiler expects them to be (f.e., you will be
in trouble if the last line has no LF).
That's why I never check End_Of_File, but handle the End_Error
exception. It always works.
On 2023-09-23 10:02, J-P. Rosen wrote:
That's why I never check End_Of_File, but handle the End_Error
exception. It always works.
True, but it may not be convenient for the overall logic of the program
that reads the file. That program often wants do to something with the contents, after reading the whole file, and having to enter that part of
the program through an exception does complicate the code a little.
On 2023-09-23 10:39, Niklas Holsti wrote:
On 2023-09-23 10:02, J-P. Rosen wrote:
That's why I never check End_Of_File, but handle the End_Error
exception. It always works.
True, but it may not be convenient for the overall logic of the
program that reads the file. That program often wants do to something
with the contents, after reading the whole file, and having to enter
that part of the program through an exception does complicate the code
a little.
It rather simplifies the code.
You exit the loop and do whatever is necessary there.
Testing for the file end is unreliable and non-portable. Many types
of files simply do not support that test.In other cases the test is
not file immutable with the side effects that can change the program
logic.
On 2023-09-23 12:25, Dmitry A. Kazakov wrote:
You exit the loop and do whatever is necessary there.
That is exactly what happens in the "while not End_Of_File" loop.
If you want to use End_Error instead, you have to add an exception
handler, and if you want to stay in the subprogram's statement sequence without entering the subprogram-level exception handlers, you have to
add a block to contain the reading loop and make the exception handler
local to that block.
To me that looks like adding code -> more complex. Of course not much
more complex, but a little, as I said.
Testing for the file end is unreliable and non-portable. Many types
of files simply do not support that test.In other cases the test is
not file immutable with the side effects that can change the program
logic.
I suppose you are talking about the need for End_Of_File to possibly
read ahead past a line terminator? If not, please clarify.
On 2023-09-23 16:03, Niklas Holsti wrote:21:30, Blady wrote:
On 2023-09-23 10:02, J-P. Rosen wrote: >>> Le 22/09/2023 à 22:05, Jeffrey R.Carter a écrit :>>>> On 2023-09-22
A.10.7 Input-Output of Characters and Strings
For an item of type Character the following procedures are provided:
procedure Get(File : in File_Type; Item : out Character);
procedure Get(Item : out Character);
After skipping any line terminators and any page terminators, reads
the next character from the specified input file and returns the
value of this character in the out parameter Item.
The exception End_Error is propagated if an attempt is made to skip
a file terminator.
Le 22/09/2023 à 22:05, Jeffrey R.Carter a écrit :
On 2023-09-22 21:30, Blady wrote:And this works only if the input file is "well formed", i.e. if it has
A.10.7 Input-Output of Characters and Strings
For an item of type Character the following procedures are provided:
procedure Get(File : in File_Type; Item : out Character);
procedure Get(Item : out Character);
After skipping any line terminators and any page terminators, reads the
next character from the specified input file and returns the value of
this character in the out parameter Item.
The exception End_Error is propagated if an attempt is made to skip a
file terminator.
As you have quoted, Get (Character) skips line terminators. End_Of_File
returns True if there is a single line terminator before the file
terminator, but False if there are multiple line terminators before the
file terminator. So you either have to explicitly skip line terminators,
or handle End_Error.
line terminators as the compiler expects them to be (f.e., you will be in trouble if the last line has no LF).
That's why I never check End_Of_File, but handle the End_Error exception.
It always works.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 379 |
Nodes: | 16 (2 / 14) |
Uptime: | 44:03:54 |
Calls: | 8,141 |
Calls today: | 4 |
Files: | 13,085 |
Messages: | 5,857,952 |