How to read the last line before the EOF is reached?

  • Follow


Hello,

I encountered a problem reading data from a file (minProgram.inp) and
filling an array with it. I've formulated am minimal example, let me
give you the code first (never mind the German comments):

----------------minProgram.inp, _four_ lines-------------
3
-2.0	4.0
0.0	0.0
2.0	4.0
--------------------------------------------------------------

----------------minProgram.f90--------------------------------
program main
implicit none

		integer :: io_error, read_error
		integer :: ii
		real(8) :: xWert, yWert
		integer :: nInterp
		real(8), allocatable :: potAr(:,:)

		open(unit=20,file='minProgram.inp', form='formatted',
status='old',action='read', &
		iostat=io_error)

		if (io_error == 0) then

			read(20,*,iostat=read_error) nInterp
			if ( read_error > 0) then
				stop "Datenfehler auf der Datei"
			end if

			allocate(potAr(nInterp,2))

			ii=1;

			do
				read(20,*,iostat=read_error) xWert, yWert
				if ( read_error > 0) then
					stop "Datenfehler auf der Datei"
				else if (read_error < 0 ) then
					write (*,*) 'EOF'
					exit
				else
					potAr(ii,1)=xWert
					potAr(ii,2)=yWert
					 write(*,*) ii,'-te Zeile:', potAr(ii,1), potAr(ii,2)
					ii = ii + 1
				end if
			end do
		else
			write(*,*) 'Beim OEffenen der Datei ist ein Fehler Nr.', &
				io_error,' aufgetreten'
		end if

		close(unit=20)

end program main
--------------------------------------------------------------

If I compile the program with gfortran, that is $ gfortran -o test
minProgram.f90 and then execute it via $ ./test, this is the

--------------output-------------------------------------
           1 -te Zeile:  -2.00000000000000        4.00000000000000
           2 -te Zeile:   0.00000000000000        0.00000000000000
EOF
----------------------------------------------------------

I simpliy can't figure out why the last line is not read. However, if
I modify the input file by starting a fifth line (only starting it by
pressing enter after the fourth line), the input file looks like this:

----------------minProgram.inp, _five_ lines-------------
3
-2.0	4.0
0.0	0.0
2.0	4.0

--------------------------------------------------------------

Then the output is correct, as it contains the last line:

--------------output-------------------------------------
           1 -te Zeile:  -2.00000000000000        4.00000000000000
           2 -te Zeile:   0.00000000000000        0.00000000000000
           3 -te Zeile:   2.00000000000000        4.00000000000000
 EOF
----------------------------------------------------------

I would like my program to read all of the lines including the last
one, even if the input file only consists of four lines. If it
consists of five or more lines, I would ignore the irrelevant lines by
making my loop go from 1 to nPoint, that is from 1 to 3, so there
wouldn't be any further problems.

How should I modify my program for that purpose?

I'd be grateful for some ideas!

Alexander
0
Reply alexander.erlich (43) 9/9/2009 3:15:33 PM

Alexander Erlich wrote:
> 
> Hello,
> 
> I encountered a problem reading data from a file (minProgram.inp) and
> filling an array with it. I've formulated am minimal example, let me
> give you the code first (never mind the German comments):
> 
> ----------------minProgram.inp, _four_ lines-------------
> 3
> -2.0    4.0
> 0.0     0.0
> 2.0     4.0
> --------------------------------------------------------------
> 
> ----------------minProgram.f90--------------------------------
> program main
> implicit none
> 
>                 integer :: io_error, read_error
>                 integer :: ii
>                 real(8) :: xWert, yWert
>                 integer :: nInterp
>                 real(8), allocatable :: potAr(:,:)
> 
>                 open(unit=20,file='minProgram.inp', form='formatted',
> status='old',action='read', &
>                 iostat=io_error)
> 
>                 if (io_error == 0) then
> 
>                         read(20,*,iostat=read_error) nInterp
>                         if ( read_error > 0) then
>                                 stop "Datenfehler auf der Datei"
>                         end if
> 
>                         allocate(potAr(nInterp,2))
> 
>                         ii=1;
> 
>                         do
>                                 read(20,*,iostat=read_error) xWert, yWert
>                                 if ( read_error > 0) then
>                                         stop "Datenfehler auf der Datei"
>                                 else if (read_error < 0 ) then
>                                         write (*,*) 'EOF'
>                                         exit
>                                 else
>                                         potAr(ii,1)=xWert
>                                         potAr(ii,2)=yWert
>                                          write(*,*) ii,'-te Zeile:', potAr(ii,1), potAr(ii,2)
>                                         ii = ii + 1
>                                 end if
>                         end do
>                 else
>                         write(*,*) 'Beim OEffenen der Datei ist ein Fehler Nr.', &
>                                 io_error,' aufgetreten'
>                 end if
> 
>                 close(unit=20)
> 
> end program main
> --------------------------------------------------------------
> 
> If I compile the program with gfortran, that is $ gfortran -o test
> minProgram.f90 and then execute it via $ ./test, this is the
> 
> --------------output-------------------------------------
>            1 -te Zeile:  -2.00000000000000        4.00000000000000
>            2 -te Zeile:   0.00000000000000        0.00000000000000
> EOF
> ----------------------------------------------------------
> 
> I simpliy can't figure out why the last line is not read. However, if
> I modify the input file by starting a fifth line (only starting it by
> pressing enter after the fourth line), the input file looks like this:
> 
> ----------------minProgram.inp, _five_ lines-------------
> 3
> -2.0    4.0
> 0.0     0.0
> 2.0     4.0
> 
> --------------------------------------------------------------
> 
> Then the output is correct, as it contains the last line:
> 
> --------------output-------------------------------------
>            1 -te Zeile:  -2.00000000000000        4.00000000000000
>            2 -te Zeile:   0.00000000000000        0.00000000000000
>            3 -te Zeile:   2.00000000000000        4.00000000000000
>  EOF
> ----------------------------------------------------------
> 
> I would like my program to read all of the lines including the last
> one, even if the input file only consists of four lines. If it
> consists of five or more lines, I would ignore the irrelevant lines by
> making my loop go from 1 to nPoint, that is from 1 to 3, so there
> wouldn't be any further problems.
> 
> How should I modify my program for that purpose?
> 
> I'd be grateful for some ideas!

It looks like the last line of minProgram.inp is missing the end-of-line
character (line feed or return, system dependent).  This would exactly
explain your mysterious symptom.

In general, fortran requires a line terminator character on each line
read in regular sequential text mode.  There are complicated workarounds
possible, but best practice is to simply ensure that the last line of
every text file includes the correct line terminator.  HTH.

--Dave
0
Reply nospom (125) 9/9/2009 3:39:00 PM


Dave Allured wrote:
> 
> Alexander Erlich wrote:
> >
> > Hello,
> >
> > I encountered a problem reading data from a file (minProgram.inp) and
> > filling an array with it. I've formulated am minimal example, let me
> > give you the code first (never mind the German comments):
> >
> > ----------------minProgram.inp, _four_ lines-------------
> > 3
> > -2.0    4.0
> > 0.0     0.0
> > 2.0     4.0
> > --------------------------------------------------------------
> >
> > ----------------minProgram.f90--------------------------------
> > program main
> > implicit none
> >
> >                 integer :: io_error, read_error
> >                 integer :: ii
> >                 real(8) :: xWert, yWert
> >                 integer :: nInterp
> >                 real(8), allocatable :: potAr(:,:)
> >
> >                 open(unit=20,file='minProgram.inp', form='formatted',
> > status='old',action='read', &
> >                 iostat=io_error)
> >
> >                 if (io_error == 0) then
> >
> >                         read(20,*,iostat=read_error) nInterp
> >                         if ( read_error > 0) then
> >                                 stop "Datenfehler auf der Datei"
> >                         end if
> >
> >                         allocate(potAr(nInterp,2))
> >
> >                         ii=1;
> >
> >                         do
> >                                 read(20,*,iostat=read_error) xWert, yWert
> >                                 if ( read_error > 0) then
> >                                         stop "Datenfehler auf der Datei"
> >                                 else if (read_error < 0 ) then
> >                                         write (*,*) 'EOF'
> >                                         exit
> >                                 else
> >                                         potAr(ii,1)=xWert
> >                                         potAr(ii,2)=yWert
> >                                          write(*,*) ii,'-te Zeile:', potAr(ii,1), potAr(ii,2)
> >                                         ii = ii + 1
> >                                 end if
> >                         end do
> >                 else
> >                         write(*,*) 'Beim OEffenen der Datei ist ein Fehler Nr.', &
> >                                 io_error,' aufgetreten'
> >                 end if
> >
> >                 close(unit=20)
> >
> > end program main
> > --------------------------------------------------------------
> >
> > If I compile the program with gfortran, that is $ gfortran -o test
> > minProgram.f90 and then execute it via $ ./test, this is the
> >
> > --------------output-------------------------------------
> >            1 -te Zeile:  -2.00000000000000        4.00000000000000
> >            2 -te Zeile:   0.00000000000000        0.00000000000000
> > EOF
> > ----------------------------------------------------------
> >
> > I simpliy can't figure out why the last line is not read. However, if
> > I modify the input file by starting a fifth line (only starting it by
> > pressing enter after the fourth line), the input file looks like this:
> >
> > ----------------minProgram.inp, _five_ lines-------------
> > 3
> > -2.0    4.0
> > 0.0     0.0
> > 2.0     4.0
> >
> > --------------------------------------------------------------
> >
> > Then the output is correct, as it contains the last line:
> >
> > --------------output-------------------------------------
> >            1 -te Zeile:  -2.00000000000000        4.00000000000000
> >            2 -te Zeile:   0.00000000000000        0.00000000000000
> >            3 -te Zeile:   2.00000000000000        4.00000000000000
> >  EOF
> > ----------------------------------------------------------
> >
> > I would like my program to read all of the lines including the last
> > one, even if the input file only consists of four lines. If it
> > consists of five or more lines, I would ignore the irrelevant lines by
> > making my loop go from 1 to nPoint, that is from 1 to 3, so there
> > wouldn't be any further problems.
> >
> > How should I modify my program for that purpose?
> >
> > I'd be grateful for some ideas!
> 
> It looks like the last line of minProgram.inp is missing the end-of-line
> character (line feed or return, system dependent).  This would exactly
> explain your mysterious symptom.
> 
> In general, fortran requires a line terminator character on each line
> read in regular sequential text mode.  There are complicated workarounds
> possible, but best practice is to simply ensure that the last line of
> every text file includes the correct line terminator.  HTH.

P.S.  To confirm this hypothesis, examine the file character by
character with a dump utility, e.g.

  od -Ad -c minProgram.inp

Typically the last character in the file should be \n ("newline" AKA
line feed) on unix-like systems, or \r ("return") on some other
systems.  The two-character sequence \r \n (AKA CR-LF) is common on
older DOS and Windows systems; I am not sure how widespread this is
today.  Sorry about all the diverse acronyms; that's evolution for you.

In any case, you want the last line to terminate the same way as all the
other lines in the file.

--Dave
0
Reply nospom (125) 9/9/2009 3:58:11 PM

Hi Dave,

thanks a lot, you are perfectly right. Here's the confirmation:

With minProgram.inp having four lines, I get no line terminating \n :
$ od -Ad -c minProgram.inp
0000000   3  \n   -   2   .   0  \t   4   .   0  \n   0   .   0  \t
0
0000016   .   0  \n   2   .   0  \t   4   .   0
0000026


But with five line version, I do:
$ od -Ad -c minProgram.inp
0000000   3  \n   -   2   .   0  \t   4   .   0  \n   0   .   0  \t
0
0000016   .   0  \n   2   .   0  \t   4   .   0  \n
0000027

Thanks, that's a good thing to know :-)

Regards,
Alexander


On Sep 9, 5:58=A0pm, Dave Allured <nos...@nospom.com> wrote:
> Dave Allured wrote:
>
> > Alexander Erlich wrote:
>
> > > Hello,
>
> > > I encountered a problem reading data from a file (minProgram.inp) and
> > > filling an array with it. I've formulated am minimal example, let me
> > > give you the code first (never mind the German comments):
>
> > > ----------------minProgram.inp, _four_ lines-------------
> > > 3
> > > -2.0 =A0 =A04.0
> > > 0.0 =A0 =A0 0.0
> > > 2.0 =A0 =A0 4.0
> > > --------------------------------------------------------------
>
> > > ----------------minProgram.f90--------------------------------
> > > program main
> > > implicit none
>
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 integer :: io_error, read_error
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 integer :: ii
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 real(8) :: xWert, yWert
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 integer :: nInterp
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 real(8), allocatable :: potAr(:,:)
>
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 open(unit=3D20,file=3D'minProgram.inp=
', form=3D'formatted',
> > > status=3D'old',action=3D'read', &
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 iostat=3Dio_error)
>
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (io_error =3D=3D 0) then
>
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 read(20,*,iostat=3Dre=
ad_error) nInterp
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ( read_error > 0) =
then
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 stop =
"Datenfehler auf der Datei"
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end if
>
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 allocate(potAr(nInter=
p,2))
>
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ii=3D1;
>
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 do
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 read(=
20,*,iostat=3Dread_error) xWert, yWert
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ( =
read_error > 0) then
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 stop "Datenfehler auf der Datei"
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else =
if (read_error < 0 ) then
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 write (*,*) 'EOF'
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 exit
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 potAr(ii,1)=3DxWert
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 potAr(ii,2)=3DyWert
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 =A0write(*,*) ii,'-te Zeile:', potAr(ii,1), potAr(ii,2)
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 ii =3D ii + 1
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end i=
f
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end do
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 write(*,*) 'Beim OEff=
enen der Datei ist ein Fehler Nr.', &
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 io_er=
ror,' aufgetreten'
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end if
>
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 close(unit=3D20)
>
> > > end program main
> > > --------------------------------------------------------------
>
> > > If I compile the program with gfortran, that is $ gfortran -o test
> > > minProgram.f90 and then execute it via $ ./test, this is the
>
> > > --------------output-------------------------------------
> > > =A0 =A0 =A0 =A0 =A0 =A01 -te Zeile: =A0-2.00000000000000 =A0 =A0 =A0 =
=A04.00000000000000
> > > =A0 =A0 =A0 =A0 =A0 =A02 -te Zeile: =A0 0.00000000000000 =A0 =A0 =A0 =
=A00.00000000000000
> > > EOF
> > > ----------------------------------------------------------
>
> > > I simpliy can't figure out why the last line is not read. However, if
> > > I modify the input file by starting a fifth line (only starting it by
> > > pressing enter after the fourth line), the input file looks like this=
:
>
> > > ----------------minProgram.inp, _five_ lines-------------
> > > 3
> > > -2.0 =A0 =A04.0
> > > 0.0 =A0 =A0 0.0
> > > 2.0 =A0 =A0 4.0
>
> > > --------------------------------------------------------------
>
> > > Then the output is correct, as it contains the last line:
>
> > > --------------output-------------------------------------
> > > =A0 =A0 =A0 =A0 =A0 =A01 -te Zeile: =A0-2.00000000000000 =A0 =A0 =A0 =
=A04.00000000000000
> > > =A0 =A0 =A0 =A0 =A0 =A02 -te Zeile: =A0 0.00000000000000 =A0 =A0 =A0 =
=A00.00000000000000
> > > =A0 =A0 =A0 =A0 =A0 =A03 -te Zeile: =A0 2.00000000000000 =A0 =A0 =A0 =
=A04.00000000000000
> > > =A0EOF
> > > ----------------------------------------------------------
>
> > > I would like my program to read all of the lines including the last
> > > one, even if the input file only consists of four lines. If it
> > > consists of five or more lines, I would ignore the irrelevant lines b=
y
> > > making my loop go from 1 to nPoint, that is from 1 to 3, so there
> > > wouldn't be any further problems.
>
> > > How should I modify my program for that purpose?
>
> > > I'd be grateful for some ideas!
>
> > It looks like the last line of minProgram.inp is missing the end-of-lin=
e
> > character (line feed or return, system dependent). =A0This would exactl=
y
> > explain your mysterious symptom.
>
> > In general, fortran requires a line terminator character on each line
> > read in regular sequential text mode. =A0There are complicated workarou=
nds
> > possible, but best practice is to simply ensure that the last line of
> > every text file includes the correct line terminator. =A0HTH.
>
> P.S. =A0To confirm this hypothesis, examine the file character by
> character with a dump utility, e.g.
>
> =A0 od -Ad -c minProgram.inp
>
> Typically the last character in the file should be \n ("newline" AKA
> line feed) on unix-like systems, or \r ("return") on some other
> systems. =A0The two-character sequence \r \n (AKA CR-LF) is common on
> older DOS and Windows systems; I am not sure how widespread this is
> today. =A0Sorry about all the diverse acronyms; that's evolution for you.
>
> In any case, you want the last line to terminate the same way as all the
> other lines in the file.
>
> --Dave

0
Reply alexander.erlich (43) 9/9/2009 6:33:04 PM

Am 09.09.2009 17:39, schrieb Dave Allured:
> It looks like the last line of minProgram.inp is missing the end-of-line
> character (line feed or return, system dependent).  This would exactly
> explain your mysterious symptom.
> 
> In general, fortran requires a line terminator character on each line
> read in regular sequential text mode.  There are complicated workarounds
> possible, but best practice is to simply ensure that the last line of
> every text file includes the correct line terminator.  HTH.

To add: Most editors add a line terminator also at the end of the last
line. I agree that one increases the portability if the file has such a
line terminator. I am not sure whether the Fortran standard requires it,
my guess would be that it doesn't.

Newer gfortran compilers (starting from GCC 4.3) also work if the last
line does not end with a new-line character thus updating GCC would be
also an option. (GCC 4.3.4 and 4.4.1 are the currently supported
versions; 4.5.0(experimental) is the current developer version.)

Tobias

PS: GCC release notes etc., see http://gcc.gnu.org/
GCC/gfortran (not all) nightly builds:
http://gcc.gnu.org/wiki/GFortranBinaries
0
Reply burnus (564) 9/10/2009 6:30:58 AM

Tobias Burnus <burnus@net-b.de> wrote:

> To add: Most editors add a line terminator also at the end of the last
> line. I agree that one increases the portability if the file has such a
> line terminator. I am not sure whether the Fortran standard requires it,
> my guess would be that it doesn't.

The Fortran standard does not explicitly talk about such things. The
details of how a text record is formed are left to the operating system.
However...

The Fortran standard does say that a sequential file is composed of
records. If a text record is defined to include a line terminator, then
that's what the Fortran standard requires. Since the definition of a
text record is not specified by the standard, there is some leeway here,
but I'd say that the traditional definition would require that a text
record include a termintor character (on appropriate systems; the
question is moot on systems that don't use terminator characters to form
text records). If the terminator is missing, there is only a partial
record.

Certainly there have been plenty of Fortran compilers over the years
that did not deal with such partial records.

F2003 introduced stream files, along with concepts of partial records,
so that makes the picture fuzzier.

-- 
Richard Maine                    | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle           |  -- Mark Twain
0
Reply nospam47 (9742) 9/10/2009 7:49:27 AM

On Sep 10, 2:49=A0am, nos...@see.signature (Richard Maine) wrote:
> Tobias Burnus <bur...@net-b.de> wrote:
> > To add: Most editors add a line terminator also at the end of the last
> > line. I agree that one increases the portability if the file has such a
> > line terminator. I am not sure whether the Fortran standard requires it=
,
> > my guess would be that it doesn't.
>
> The Fortran standard does not explicitly talk about such things. The
> details of how a text record is formed are left to the operating system.
> However...
>
> The Fortran standard does say that a sequential file is composed of
> records. If a text record is defined to include a line terminator, then
> that's what the Fortran standard requires. Since the definition of a
> text record is not specified by the standard, there is some leeway here,
> but I'd say that the traditional definition would require that a text
> record include a termintor character (on appropriate systems; the
> question is moot on systems that don't use terminator characters to form
> text records). If the terminator is missing, there is only a partial
> record.
>
> Certainly there have been plenty of Fortran compilers over the years
> that did not deal with such partial records.
>
> F2003 introduced stream files, along with concepts of partial records,
> so that makes the picture fuzzier.
>

On some systems, there is a concept called a "record separator" (RS).
The last record may not have one because there is no subsequent record
to separate.  The file would instead end with an "end of file" marker
and possibly an "end of tape" marker if no additional file segments
are present.


> --
> Richard Maine =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| Good judgment come=
s from experience;
> email: last name at domain . net | experience comes from bad judgment.
> domain: summertriangle =A0 =A0 =A0 =A0 =A0 | =A0-- Mark Twain

0
Reply garylscott (1357) 9/10/2009 3:36:33 PM

On Sep 9, 2:33=A0pm, Alexander Erlich <alexander.erl...@gmail.com>
wrote:
> Hi Dave,
>
> thanks a lot, you are perfectly right. Here's the confirmation:
>
> With minProgram.inp having four lines, I get no line terminating \n :
> $ od -Ad -c minProgram.inp
> 0000000 =A0 3 =A0\n =A0 - =A0 2 =A0 . =A0 0 =A0\t =A0 4 =A0 . =A0 0 =A0\n=
 =A0 0 =A0 . =A0 0 =A0\t
> 0
> 0000016 =A0 . =A0 0 =A0\n =A0 2 =A0 . =A0 0 =A0\t =A0 4 =A0 . =A0 0
> 0000026
>
> But with five line version, I do:
> $ od -Ad -c minProgram.inp
> 0000000 =A0 3 =A0\n =A0 - =A0 2 =A0 . =A0 0 =A0\t =A0 4 =A0 . =A0 0 =A0\n=
 =A0 0 =A0 . =A0 0 =A0\t
> 0
> 0000016 =A0 . =A0 0 =A0\n =A0 2 =A0 . =A0 0 =A0\t =A0 4 =A0 . =A0 0 =A0\n
> 0000027
>
> Thanks, that's a good thing to know :-)
>
> Regards,
> Alexander
>
> On Sep 9, 5:58=A0pm, Dave Allured <nos...@nospom.com> wrote:
>
> > Dave Allured wrote:
>
> > > Alexander Erlich wrote:
>
> > > > Hello,
>
> > > > I encountered a problem reading data from a file (minProgram.inp) a=
nd
> > > > filling an array with it. I've formulated am minimal example, let m=
e
> > > > give you the code first (never mind the German comments):
>
> > > > ----------------minProgram.inp, _four_ lines-------------
> > > > 3
> > > > -2.0 =A0 =A04.0
> > > > 0.0 =A0 =A0 0.0
> > > > 2.0 =A0 =A0 4.0
> > > > --------------------------------------------------------------
>
> > > > ----------------minProgram.f90--------------------------------
> > > > program main
> > > > implicit none
>
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 integer :: io_error, read_error
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 integer :: ii
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 real(8) :: xWert, yWert
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 integer :: nInterp
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 real(8), allocatable :: potAr(:,:)
>
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 open(unit=3D20,file=3D'minProgram.i=
np', form=3D'formatted',
> > > > status=3D'old',action=3D'read', &
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 iostat=3Dio_error)
>
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (io_error =3D=3D 0) then
>
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 read(20,*,iostat=3D=
read_error) nInterp
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ( read_error > 0=
) then
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 sto=
p "Datenfehler auf der Datei"
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end if
>
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 allocate(potAr(nInt=
erp,2))
>
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ii=3D1;
>
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 do
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 rea=
d(20,*,iostat=3Dread_error) xWert, yWert
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if =
( read_error > 0) then
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 stop "Datenfehler auf der Datei"
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 els=
e if (read_error < 0 ) then
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 write (*,*) 'EOF'
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 exit
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 els=
e
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 potAr(ii,1)=3DxWert
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 potAr(ii,2)=3DyWert
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 =A0write(*,*) ii,'-te Zeile:', potAr(ii,1), potAr(ii,2)
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 ii =3D ii + 1
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end=
 if
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end do
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 write(*,*) 'Beim OE=
ffenen der Datei ist ein Fehler Nr.', &
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 io_=
error,' aufgetreten'
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end if
>
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 close(unit=3D20)
>
> > > > end program main
> > > > --------------------------------------------------------------
>
> > > > If I compile the program with gfortran, that is $ gfortran -o test
> > > > minProgram.f90 and then execute it via $ ./test, this is the
>
> > > > --------------output-------------------------------------
> > > > =A0 =A0 =A0 =A0 =A0 =A01 -te Zeile: =A0-2.00000000000000 =A0 =A0 =
=A0 =A04.00000000000000
> > > > =A0 =A0 =A0 =A0 =A0 =A02 -te Zeile: =A0 0.00000000000000 =A0 =A0 =
=A0 =A00.00000000000000
> > > > EOF
> > > > ----------------------------------------------------------
>
> > > > I simpliy can't figure out why the last line is not read. However, =
if
> > > > I modify the input file by starting a fifth line (only starting it =
by
> > > > pressing enter after the fourth line), the input file looks like th=
is:
>
> > > > ----------------minProgram.inp, _five_ lines-------------
> > > > 3
> > > > -2.0 =A0 =A04.0
> > > > 0.0 =A0 =A0 0.0
> > > > 2.0 =A0 =A0 4.0
>
> > > > --------------------------------------------------------------
>
> > > > Then the output is correct, as it contains the last line:
>
> > > > --------------output-------------------------------------
> > > > =A0 =A0 =A0 =A0 =A0 =A01 -te Zeile: =A0-2.00000000000000 =A0 =A0 =
=A0 =A04.00000000000000
> > > > =A0 =A0 =A0 =A0 =A0 =A02 -te Zeile: =A0 0.00000000000000 =A0 =A0 =
=A0 =A00.00000000000000
> > > > =A0 =A0 =A0 =A0 =A0 =A03 -te Zeile: =A0 2.00000000000000 =A0 =A0 =
=A0 =A04.00000000000000
> > > > =A0EOF
> > > > ----------------------------------------------------------
>
> > > > I would like my program to read all of the lines including the last
> > > > one, even if the input file only consists of four lines. If it
> > > > consists of five or more lines, I would ignore the irrelevant lines=
 by
> > > > making my loop go from 1 to nPoint, that is from 1 to 3, so there
> > > > wouldn't be any further problems.
>
> > > > How should I modify my program for that purpose?
>
> > > > I'd be grateful for some ideas!
>
> > > It looks like the last line of minProgram.inp is missing the end-of-l=
ine
> > > character (line feed or return, system dependent). =A0This would exac=
tly
> > > explain your mysterious symptom.
>
> > > In general, fortran requires a line terminator character on each line
> > > read in regular sequential text mode. =A0There are complicated workar=
ounds
> > > possible, but best practice is to simply ensure that the last line of
> > > every text file includes the correct line terminator. =A0HTH.
>
> > P.S. =A0To confirm this hypothesis, examine the file character by
> > character with a dump utility, e.g.
>
> > =A0 od -Ad -c minProgram.inp
>
> > Typically the last character in the file should be \n ("newline" AKA
> > line feed) on unix-like systems, or \r ("return") on some other
> > systems. =A0The two-character sequence \r \n (AKA CR-LF) is common on
> > older DOS and Windows systems; I am not sure how widespread this is
> > today. =A0Sorry about all the diverse acronyms; that's evolution for yo=
u.
>
> > In any case, you want the last line to terminate the same way as all th=
e
> > other lines in the file.
>
> > --Dave
>
>


Sounds like a flaky text editor was used. Perhaps Notepad under
Windows ?

I have seen strange things happen when an eol character was missing on
the last line of a header file which was then included into a C source
code file. Learned to always hit the carriage retun on the last line
when editing with Notepad.






0
Reply bobk1955 (3) 9/11/2009 2:19:29 AM

> Sounds like a flaky text editor was used. Perhaps Notepad under
> Windows ?

No, it was kate. But still, you're right! I always edited the input
file with kate, but the problem does not occur with e.g. emacs or
gedit!

Regards,
Alexander

0
Reply alexander.erlich (43) 9/16/2009 7:38:10 PM

8 Replies
43 Views

(page loaded in 0.201 seconds)

Similiar Articles:













7/29/2012 10:53:14 PM


Reply: