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: fgets / read / select - comp.unix.programmer... block buffered", and EOF is flagged when the end of the file is reached. When reading from a tty the mode is "line buffered" and there is no EOF ... with 2,808 bytes, last ... Reading a Line from a file - comp.soft-sys.matlab... file, that I would just like to be able to read specific lines ... on a DEC VAX computer with VMS that dates before ... as lines of text and write all but the last line of ... Error in reading compressed file - comp.soft-sys.sasIf I manually delete the last = line then SAS can read the file easily. ... to show an example of my suggestion but, before ... way, may only entail using something like eof ... File read failure - comp.lang.cWhat is the character after the last character read? ... by changing the data, especially the lines before the ... EOF error. - comp.lang.vhdl ifstream open ... sed: add newline if no eol? - comp.unix.solaris... help me with a sed command to add a newline to the last line ... When I read your question I remembered that 'wc' and ... ECHO;wasnl=0;} \n {ECHO;wasnl=1;} <<EOF ... Cursor jumps to center while scrolling... - comp.emacs... in some situations (like next-screen-line still scrolling down even if EOF is reached ... How to Automatically Scroll While Reading ... part1 Posting-Frequency: monthly Last ... @ symbol deleting all preceeding input at command line? - comp.sys ...... he types the "@" (at-symbol) on the command line ... If you had read the reference which I gave, termio(7 ... I'm sure no-one has ever heard that 'joke' before. How to optimize primary key change on a large table? - comp ...I have read that changing primary keys is a very time ... Really, you should get the inserts off-line before doing ... three hundred thousand years before BIGINT reached its ... Syntax error trying to return scalar value from query in stored ...... e. read rows in specified order and stop reading when the LIMIT is reached ... delimiter ; > not sure how the last ... at the ... of that error message: near EOF ... comp.lang.java.help - page 20Articles (1310) |<First << Prev /131 Next>> Last >| ... that rather than do some sort of fancy checking before ... int values between 0 and 255, or -1 when EOF is reached. End-of-file - Wikipedia, the free encyclopediaBlock-reading functions return the number of bytes read, and if this is fewer than asked for, then the end of file was reached. ... This page was last modified ... Premature EOF while reading from Inputstream (I/O and Streams ...Instead of after reading last line, it should attempt to read next line which will be EOF, but while ... stream terminated before I reached EOF, ... 7/29/2012 10:53:14 PM
|