1

I am trying to open an ASCII file with unknown number of lines (but fixed number of entries in each line - please see example file below). It goes to the end of the file, but fails after that.

Option 1: Using iostat statement: I get the same error when using either "Use, intrinsic :: iso_fortran_env, Only : iostat_end" or simply treating io as an integer.

Option 2: Using "end= .." option. This is what I have used earlier (F77).

Both approaches should work in principle, but neither does. Any help in fixing this will be greatly appreciated.

Thanks, Pinaki.

Program:

!=======================================!
program read
!=======================================!
!  Use, intrinsic :: iso_fortran_env, Only : iostat_end
  implicit none

  integer :: i,io,n     

  n=0
  open(10,file='a.dat',status='old',action='read')

!=================================!
! option 1
!=================================!  
  do 
     read(10,*,iostat=io)
     write(*,*)io
!     if (io.eq.iostat_end) exit
     if (io.ne.0) exit
     n=n+1
     write(*,*)'n=',n
  enddo
!=================================!

!=================================!
! option 2
!=================================!
  do 10 i=1,1000000
     read(10,*,end=10)
     n=n+1
     write(*,*)n
10   continue
!================================!

  close(10)
  write(*,*)'n=',n
  
end program read
!======================!

Compiled using "gfortran --std=f2003 -o read.out read.f90"

Error message:

==============================================

dyld: lazy symbol binding failed: Symbol not found: ___emutls_get_address
  Referenced from: /usr/local/opt/gcc/lib/gcc/11/libgfortran.5.dylib
  Expected in: /usr/lib/libSystem.B.dylib

dyld: Symbol not found: ___emutls_get_address
  Referenced from: /usr/local/opt/gcc/lib/gcc/11/libgfortran.5.dylib
  Expected in: /usr/lib/libSystem.B.dylib

Program received signal SIGABRT: Process abort signal.

Backtrace for this error: #0 0x105364f8e #1 0x10536419d #2 0x7fff6eed05fc zsh: abort ./read.out

=====================================================

File I am trying to read:

=====================================================

 1    -1.1559859375    2.0399371094    0.1686166667    0.8242152778
  2    -1.1618015625    2.1375250000    0.1765231481    0.8105046296
  3    -1.1696710937    2.2325417969    0.1860513889    0.7936782407
  1    -1.1730312500    2.3271382813    0.1975254630    0.7718773148
  2    -1.1767945313    2.3942726563    0.2113162500    0.7446933333
  3    -1.1694437500    2.4738000000    0.2281966667    0.7099266667
  1    -1.1566140625    2.5312164063    0.2494466667    0.6636841667
  2    -1.1293765625    2.5746707031    0.2747766667    0.6066154167
  3    -1.0836390625    2.5938144531    0.3026616667    0.5403733333
  1    -1.0380632812    2.5721433594    0.3302462121    0.4727159091

=======================================================================

Ian Bush
  • 6,996
  • 1
  • 21
  • 27
pinaki
  • 11
  • 3
  • 3
    Apart from fortran codes, doesn't the error message show some installation problem of the compiler? (e.g. due to multiple installations and wrong dynamic libraries?) something like... https://stackoverflow.com/questions/13414786/missing-emutls-get-address-with-gcc-4-7-and-openmp – roygvib Jul 03 '21 at 08:40

1 Answers1

2

I tested your code, the first option worked. Your second option would also work if you remove the label 10 from do 10 i=1,1000000 and add a end do right before 10 continue. You would also have to add a rewind(10) or close(10); open(10,file='a.dat',status='old',action='read') right before the second option's do loop. But more interestingly, this problem is very easy to solve in Fortran 2008 using the is_iostat_end() intrinsic function that checks for the end-of-file error code occurrence. Here is a modern implementation,

program read
    implicit none
    integer :: i, n, iostat, fileUnit
    n = 0
    open(newunit = fileUnit, file = 'a.dat', status = 'old', action = 'read')
    do
         read(fileUnit,*,iostat = iostat)
         if (is_iostat_end(iostat)) exit
         write(*,*) iostat
         n = n + 1
         write(*,*)'n = ', n
    end do
    close(fileUnit)
end program read

Compile and rune it with the following commands,

gfortran --std=f2008 -o read.out read.f90
./read.out

Even though the problem was trivial, you asked a very nice question by providing a full code, data files, a recipe to compile the code, and the errors encountered. It deserves an upvote.

Scientist
  • 1,767
  • 2
  • 12
  • 20
  • 1
    Well, if you tried the original code as written, the second option will **never work** after the code for the first option executes. Here, **never work** means to give the desired result. Prior to executing the Option 2 loop, one needs to set `n = 0 ` and `rewind(10)`. – steve Jul 03 '21 at 04:32
  • 1
    Setting `n = 0` does not do anything. I tried `close(10); open(...)` before, but `rewind(10)` is nicer. But even that is not enough. The issue is with the wrong exit line `10 continue`. I have added a solution to the answer. Thanks for providing the motivation to dig into this more. – Scientist Jul 03 '21 at 04:59
  • @roygvib Thanks for the careful observation. In this particular case, it is irrelevant since it is in the main code and executes only once. But I understand your concern and actually thought about this common misunderstanding when writing it. fixed. – Scientist Jul 03 '21 at 08:51
  • @king, Setting `n = 0` before Option 2 in the original code would ensure that one correctly counts the number of lines in the file if the unit had been rewound. Good catch on the branching of `end=10` to the `10 continue` line. I use the option 2 idiom in most of my codes, but my `end=10` typically branches to ` 10 rewind(unit=10)` outside of the do-loop for further processing of the file's content. – steve Jul 03 '21 at 16:21
  • @King: Thanks for your detailed answer. I really appreciate that. I should have commented out option 2 in the code as I tried either option 1 or 2, not both at the same time. Unfortunately, I still get the same error - so I guess it is a gcc installation issue as roygvib suggested. I'll try that now. – pinaki Jul 03 '21 at 21:51
  • @roygvib: Thanks for your comment and the link to the previous post - I think that is the main issue. I'll try to reinstall gcc and hope that it fixes the problem. – pinaki Jul 03 '21 at 21:58
  • @steve: I'm sorry for my sloppiness - I should have commented out Option 2. I tried both options, but not simultaneously. Thanks for suggesting the rewind command - I did not know of that previously. – pinaki Jul 03 '21 at 22:02