Home > Software design >  How to solve "list-directed I/O syntax error" during .CSV file reading in Fortran90?
How to solve "list-directed I/O syntax error" during .CSV file reading in Fortran90?

Time:03-19

I premise I've read many questions about this problem but I cannot solve it. During the reading of my .csv file I get the following error: forrtl: severe (59): list-directed I/O syntax error, unit 10, file D:\OneDrive\MSc_Thesis\Projects\NEOs_orbits - TEST\InputFiles\test_Ast.csv. It seems to be produced by a specific line of my .csv file attached beloew (the last one).

Here is my .CSV file:

"pdes","name","epoch","a","e","i","om","w","ma","q","ad"
1580,Betulia,2459600.5,2.197288160959855,.4871550690589618,52.07925829047207,62.2921305585828,159.5134530240992,16.62891169416756,1.126868095165017,3.267708226754692
1620,Geographos,2459600.5,1.245689288381319,.3353623816094239,13.33753650294321,337.1849253204765,276.9463790166408,300.4925456829043,.8279319618844114,1.663446614878227
1627,Ivar,2459600.5,1.86327342970777,.3967369932313492,8.451956512766827,133.120308337423,167.8035837640704,129.0289785125129,1.124043931637646,2.602502927777894
1685,Toro,2459600.5,1.367465568905196,.435966790549019,9.382739662870495,274.2362441040706,127.2114688956593,300.0617970060148,.7712959936433091,1.963635144167082
1862,Apollo,2459600.5,1.470502475713431,.5600430467767759,6.353083928279622,35.56898244993719,286.0386669340027,60.20237527657879,.6469577889220891,2.294047162504772
1863,Antinous,2459600.5,2.25922922966352,.6059920366929147,18.39886422664638,346.4237098245764,268.0896471241496,244.0101430178307,.8901543074235589,3.628304151903481
1864,Daedalus,2459600.5,1.460979692497998,.6144866009907846,22.21536437289675,6.613194571694206,325.6563726287792,196.1166696228387,.5632272471383416,2.358732137857654
1865,Cerberus,2459600.5,1.079986459127503,.4669721847798676,16.09858904525619,212.8963846822369,325.2653260753237,170.2073771841984,.57566282277606,1.584310095478947
1866,Sisyphus,2459600.5,1.893353802479725,.5383695942642949,41.20637430558688,63.47259682927852,293.0824330786623,331.1476239661798,.8740296840399557,2.912677920919495
1915,Quetzalcoatl,2459600.5,2.543790754476287,.5706410666538692,20.40472660837776,162.9348721741076,347.8091351438147,41.39145147165023,1.092199284997688,3.995382223954886
1916,Boreas,2459600.5,2.272324177667199,.4498393843780145,12.88297395642586,340.5981620510102,335.9167764123868,352.2401366045371,1.250143268478108,3.294505086856289
1917,Cuyo,2459600.5,2.14981121226236,.5054666607865446,23.95922692157032,188.2869783127825,194.5115030151171,82.2843922810623,1.063153317478631,3.236469107046088
1943,Anteros,2459600.5,1.430366783173011,.2560374828122278,8.706034969532251,246.3110706020363,338.3801329232052,173.8814283992249,1.064139272511169,1.796594293834852
1980,Tezcatlipoca,2459600.5,1.709370985747121,.3648359123967504,26.8689695764886,246.560199388918,115.4661353995156,314.1597421163634,1.085731062537538,2.333010908956705
1981,Midas,2459600.5,1.776435963774881,.6501354173857774,39.82986428861084,356.8569898560586,267.8286153975083,202.5329806814936,.621512027006993,2.931359900542769
2059,Baboquivari,2459600.5,2.64324121274608,.531432311471031,11.02055447003622,200.6851159860844,192.4190577597405,181.8930083473287,1.23853742528094,4.04794500021122
2061,Anza,2459600.5,2.264279343476608,.5360981217114927,3.800349706160866,207.3741353983842,157.0286649770264,354.1526556258232,1.050403440408666,3.478155246544549
2062,,2459600.5,.9669087478156669,.1827720931291991,18.9345273941421,108.5428491298942,148.0586126391113,21.46549438015371,.7901848121124645,1.143632683518869
"1979 XB",,2444221.5,2.228085656329666,.7084495059291489,24.73412122397795,86.0555030947377,75.57989828051527,346.3183743701075,.6495994739350907,3.806571838724241
594913,'Aylo'chaxnim,2459600.5,.5554326489245599,.1770230892406738,15.86839958719851,6.704982245275168,187.3289626591178,211.0111749229703,.4571082455468037,.6537570523023162

Here is my Fortran program (it contains a main file and some modules):

program Main_NEOs_orbits_TEST

    use DataType
    use Constants
    use DataHandling
 
    implicit none   
    
    ! Declarations
    character*100 :: input_path,output_path_ast_EM_loc, input_filename_ast,input_filename_cmt, output_path, output_filename_ast
    character*118 :: str_line
    character*2   :: str_name
    character*30, dimension (3) :: str_output    
    integer :: i,j,iflag, no_data_lines1,n_lines2, iReturn, num_orb_elem
    type(NEO), dimension (:), allocatable :: Ast_data  
  
    
    ! Definition of constants, paths names and file names
    input_path = 'D:\OneDrive\MSc_Thesis\Projects\NEOs_orbits - TEST\InputFiles\'
    input_filename_ast = 'test_Ast.csv'

        
    ! Reading of asteroids data
    call read_NEOs_data(iu_in1, input_path, input_filename_ast, no_data_lines1, Ast_data)          

    stop

end program Main_NEOs_orbits_TEST
 
**********************************************************************************************************************************************

module Constants

    use DataType

    implicit none

    real(pr), parameter :: ZERO = 0.0_pr, ONE = 1.0_pr, TWO = 2.0_pr, THREE = 3.0_pr, FOUR = 4.0_pr, SEVEN = 7.0_pr 
    real(pr), parameter :: HALF = 0.5_pr, QUART = 0.25_pr
    real(pr), parameter :: DAY = 86400.0_pr, YEAR = 365.25_pr*DAY, CENTURY =  36525.0_pr
    real(pr), parameter :: KILO = 1000.0_pr
    real(pr), parameter :: AU2Km = 149597870.700_pr  ! (from Astronomicals Unit to kilometers)
    
    real(pr), parameter :: tol = 1.e-9_pr
    real(pr), parameter :: xmu = 1.32712440018e11_pr ! (km^3 * s^-2) xmu = G * M_Sun https://ssd.jpl.nasa.gov/astro_par.html
    
    ! Unit number for files
    integer :: iu_in1 = 10   !input file
    integer :: iu_in2 = 11   !input file
    integer :: iu_out1 = 12  !output file
    integer :: iu_out2 = 13  !output file
    
end module Constants

**********************************************************************************************************************************************
module DataHandling
    
    use DataType
    
    implicit none
    
    contains 

    !***********************************************************************
    subroutine read_NEOs_data(UnitNum, FilePath, FileName, DataLinesNum, NEOs_data)
    !***********************************************************************
    ! Subroutine for reading of asteroids database 
    !***********************************************************************
    !  INPUT:

    !
    !  OUTPUT:

    !***********************************************************************
        implicit none
    
        ! Arguments
        integer, intent (in) :: UnitNum
        character (len=*), intent (in) :: FilePath
        character (len=*), intent (in) :: FileName
        integer, intent (out) :: DataLinesNum
        type(NEO), dimension (:), allocatable, intent(out) :: NEOs_data
      
        !Local variables
        integer :: i, iflag
        
        
        open(unit = UnitNum, file = trim(FilePath) // trim(FileName), status='old', & 
                access = 'sequential',form = 'formatted', action='read')
    
            ! Count lines 
            DataLinesNum = 0
            read(UnitNum,*)  ! Header line
            do     
                read(UnitNum,*,iostat = iflag)
                if (iflag/=0) exit
                DataLinesNum =  DataLinesNum   1
            enddo
         
            rewind(UnitNum)
    
            ! Variables allocation
            allocate(NEOs_data(DataLinesNum))
        
            ! Data reading 
            read(UnitNum,*)   ! skip header line (variables names will be assigned again)
            do i = 1, DataLinesNum
                read(UnitNum,*) NEOs_data(i)         
            enddo
        
        close(unit = UnitNum, status='keep') 
        
        return

    end subroutine read_NEOs_data
    !***********************************************************************
 
end module DataHandling   

**********************************************************************************************************************************************
module DataType

    implicit none

    integer, parameter :: pr = selected_real_kind (p = 15)  ! original value (p = 14) 
    
    !"NEO" data type declaration 
    type  NEO                       !  NEOs data :
        character*20 :: pdes        !  pdes      Object primary designation
        character*20 :: name        !  IAU name  Object IAU name
        real(pr) :: epoch           !  Epoch     Epoch Julian Date (TDB)
        real(pr) :: a               !  a         Semi-major axis (au)
        real(pr) :: e               !  e         Eccentricity       
        real(pr) :: i               !  i         Inclination w.r.t. xy-plane (deg)
        real(pr) :: om              !  om        Longitude of Ascending Node (deg)
        real(pr) :: w               !  w         Argument of Perihelion wrt to ecliptic/equinox (deg)
        real(pr) :: ma              !  ma        Mean anomaly (deg)
        real(pr) :: q               !  q         Perihelion distance (au)
        real(pr) :: ad              !  ad        Aphelion distance (au)
    end type NEO                    
    
end module DataType

I need to mantain the format of the .csv file, so I cannot modify it. Can you explain me why the line: 594913,'Aylo'i ,2459600.5,.5554326489245599,.1770230892406738,15.86839958719851,6.704982245275168,187.3289626591178,211.0111749229703,.4571082455468037,.6537570523023162 produces the above said error?

Error output:

forrtl: severe (59): list-directed I/O syntax error, unit 10, file D:\OneDrive\MSc_Thesis\Projects\NEOs_orbits - TEST\InputFiles\test_Ast.csv
Image              PC                Routine            Line        Source
libifcoremdd.dll   00007FFE5DBBAA5D  Unknown               Unknown  Unknown
libifcoremdd.dll   00007FFE5DC1B6FC  Unknown               Unknown  Unknown
NEOs_orbits_TEST.  00007FF75BB41B9B  DATAHANDLING_mp_R          53  DataHandling.f90
NEOs_orbits_TEST.  00007FF75BB43072  MAIN__                     57  Main_NEOs_orbits_TEST.f90
NEOs_orbits_TEST.  00007FF75BB4332E  Unknown               Unknown  Unknown
NEOs_orbits_TEST.  00007FF75BB45F69  Unknown               Unknown  Unknown
NEOs_orbits_TEST.  00007FF75BB45E8E  Unknown               Unknown  Unknown
NEOs_orbits_TEST.  00007FF75BB45D4E  Unknown               Unknown  Unknown
NEOs_orbits_TEST.  00007FF75BB45FDE  Unknown               Unknown  Unknown
KERNEL32.DLL       00007FFF269C7034  Unknown               Unknown  Unknown
ntdll.dll          00007FFF288A2651  Unknown               Unknown  Unknown

line 53: read(UnitNum,*) NEOs_data(i) line 57: call read_NEOs_data(iu_in1, input_path, input_filename_ast, no_data_lines1, Ast_data)

Problematic line: 594913,'Aylo'chaxnim,2459600.5,.5554326489245599,.1770230892406738,15.86839958719851,6.704982245275168,187.3289626591178,211.0111749229703,.4571082455468037,.6537570523023162

CodePudding user response:

The list directed format is quite convenient, but at the same time quite complicated.

In this case you are reading something that starts with an apostrophe, contains another apostrophe and hence looks like an apostrophe-delimited sequence. In apostrophe-delimited character sequences the apostrophes are delimiters and are not considered to be a part of the string. However, this 'Aylo'chaxnim is then invalid because it has another stray characters after the delimiting apostrophe. If you need to parse this, you will need some custom parser and not the generic list-directed format.

Another option is consider this 'Aylo'chaxnim to be invalid (probably entered by the data provider by mistake) and remove it before giving it to your program. either manually, if it happens only as an exception, or by some pre-processing script.

Note that if there are additional characters before the starting apostrophe, it is fine. In that case the internal apostrophes are not interpreted as delimiters, but as normal characters in the character string.


As Ian Bush shown, the name is a legitimate asteroid name. So if you need to read the correct name 'Aylo'chaxnim you will need to parse the line yourself. You can tokenize it by localizing the commas and then parse the individual tokens.

There are also CSV reader libraries available but you have to check that they are actually able to cope with this.

CodePudding user response:

Vladimir explains why you can not use list directed input for this, due to the unfortunate use of inverted commas. Here is a simple version of how I might go about addressing this problem, were I doing it properly I would package things up in modules a bit more carefully:

ijb@LAPTOP-GUG8KQ9I:~/work/stack$ cat csv.f90
Module split_string_module

  Type, Public :: split_string_token
     Character( Len = : ), Allocatable, Public :: token
  End type split_string_token

  Public :: split_string
  
  Private

Contains

  Pure Subroutine split_string( separators, string, tokens )

    ! Split a string given the separators into an array of tokens
    
    Implicit None

    Character( Len = * )                                   , Intent( In    ) :: separators
    Character( Len = * )                                   , Intent( In    ) :: string
    Type( split_string_token ), Dimension( : ), Allocatable, Intent(   Out ) :: tokens

    Type( split_string_token ) :: new_token
    
    Character( Len = : ), Allocatable :: current

    Integer :: split_point
    
    Allocate( tokens( 1:0 ) )

    current = string
    ! While we have some characters
    Do While( Len( current ) > 0 )
       ! Find the first separator
       split_point = Scan( current, separators )
       If( split_point /= 0 ) Then

          ! We have a separator - split the string at that point
          new_token%token = current( 1:split_point - 1 )
          ! Catch the case of the last character in the string being a separator
          If( split_point   1 <= Len( current ) ) Then
             current = current( split_point   1: )
          Else
             current = ''
          End If

       Else

          ! No separator found, so the remainder of the string is a token
          new_token%token = current
          current = ''

       End If

       ! Add the token to the list
       tokens = [ tokens, new_token ]

    End Do
    
  End Subroutine split_string
  
End Module split_string_module

Module read_csv_module

  Public :: read_csv_line
  
  Private
  
Contains

  Subroutine read_csv_line( unit, tokens, error )

    ! Read a line and split it into an array of comma separated tokens
    
    Use split_string_module, Only : split_string_token, split_string
    
    Implicit None

    Integer                                                , Intent( In    ) :: unit
    Type( split_string_token ), Dimension( : ), Allocatable, Intent(   Out ) :: tokens
    Integer                                                , Intent(   Out ) :: error

    Integer, Parameter :: max_line_length = 4096
    
    Character( Len = max_line_length ) :: line

    Read( unit, '( a )', iostat = error ) line
    If( error == 0 ) Then
       Call split_string( ',', Trim( line ), tokens )
    End If

  End Subroutine read_csv_line

End Module read_csv_module

Program testit

  Use read_csv_module    , Only : read_csv_line
  Use split_string_module, Only : split_string_token

  Type( split_string_token ), Dimension( : ), Allocatable :: tokens

  Integer :: unit
  Integer :: error
  Integer :: i
  
  Open( newunit = unit, file = 'input.dat' )

  error = 0
  Do While( error == 0 )
     Call read_csv_line( unit, tokens, error )
     If( error == 0 ) Then
        Do i = 1, Size( tokens )
           Write( *, '( a, 3x )', Advance = 'No' ) Trim( tokens( i )%token )
        End Do
        Write( *, * )
     End If
  End Do

  Close( unit )
  
End Program testit
ijb@LAPTOP-GUG8KQ9I:~/work/stack$ gfortran-10 --version
GNU Fortran (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

ijb@LAPTOP-GUG8KQ9I:~/work/stack$ gfortran-10 -Wall -Wextra -Wuse-without-only -Werror -fcheck=all -std=f2008 -g -O  csv.f90 
ijb@LAPTOP-GUG8KQ9I:~/work/stack$ cat input.dat 
"pdes","name","epoch","a","e","i","om","w","ma","q","ad"
1580,Betulia,2459600.5,2.197288160959855,.4871550690589618,52.07925829047207,62.2921305585828,159.5134530240992,16.62891169416756,1.126868095165017,3.267708226754692
1620,Geographos,2459600.5,1.245689288381319,.3353623816094239,13.33753650294321,337.1849253204765,276.9463790166408,300.4925456829043,.8279319618844114,1.663446614878227
1627,Ivar,2459600.5,1.86327342970777,.3967369932313492,8.451956512766827,133.120308337423,167.8035837640704,129.0289785125129,1.124043931637646,2.602502927777894
1685,Toro,2459600.5,1.367465568905196,.435966790549019,9.382739662870495,274.2362441040706,127.2114688956593,300.0617970060148,.7712959936433091,1.963635144167082
1862,Apollo,2459600.5,1.470502475713431,.5600430467767759,6.353083928279622,35.56898244993719,286.0386669340027,60.20237527657879,.6469577889220891,2.294047162504772
1863,Antinous,2459600.5,2.25922922966352,.6059920366929147,18.39886422664638,346.4237098245764,268.0896471241496,244.0101430178307,.8901543074235589,3.628304151903481
1864,Daedalus,2459600.5,1.460979692497998,.6144866009907846,22.21536437289675,6.613194571694206,325.6563726287792,196.1166696228387,.5632272471383416,2.358732137857654
1865,Cerberus,2459600.5,1.079986459127503,.4669721847798676,16.09858904525619,212.8963846822369,325.2653260753237,170.2073771841984,.57566282277606,1.584310095478947
1866,Sisyphus,2459600.5,1.893353802479725,.5383695942642949,41.20637430558688,63.47259682927852,293.0824330786623,331.1476239661798,.8740296840399557,2.912677920919495
1915,Quetzalcoatl,2459600.5,2.543790754476287,.5706410666538692,20.40472660837776,162.9348721741076,347.8091351438147,41.39145147165023,1.092199284997688,3.995382223954886
1916,Boreas,2459600.5,2.272324177667199,.4498393843780145,12.88297395642586,340.5981620510102,335.9167764123868,352.2401366045371,1.250143268478108,3.294505086856289
1917,Cuyo,2459600.5,2.14981121226236,.5054666607865446,23.95922692157032,188.2869783127825,194.5115030151171,82.2843922810623,1.063153317478631,3.236469107046088
1943,Anteros,2459600.5,1.430366783173011,.2560374828122278,8.706034969532251,246.3110706020363,338.3801329232052,173.8814283992249,1.064139272511169,1.796594293834852
1980,Tezcatlipoca,2459600.5,1.709370985747121,.3648359123967504,26.8689695764886,246.560199388918,115.4661353995156,314.1597421163634,1.085731062537538,2.333010908956705
1981,Midas,2459600.5,1.776435963774881,.6501354173857774,39.82986428861084,356.8569898560586,267.8286153975083,202.5329806814936,.621512027006993,2.931359900542769
2059,Baboquivari,2459600.5,2.64324121274608,.531432311471031,11.02055447003622,200.6851159860844,192.4190577597405,181.8930083473287,1.23853742528094,4.04794500021122
2061,Anza,2459600.5,2.264279343476608,.5360981217114927,3.800349706160866,207.3741353983842,157.0286649770264,354.1526556258232,1.050403440408666,3.478155246544549
2062,,2459600.5,.9669087478156669,.1827720931291991,18.9345273941421,108.5428491298942,148.0586126391113,21.46549438015371,.7901848121124645,1.143632683518869
"1979 XB",,2444221.5,2.228085656329666,.7084495059291489,24.73412122397795,86.0555030947377,75.57989828051527,346.3183743701075,.6495994739350907,3.806571838724241
594913,'Aylo'chaxnim,2459600.5,.5554326489245599,.1770230892406738,15.86839958719851,6.704982245275168,187.3289626591178,211.0111749229703,.4571082455468037,.6537570523023162
ijb@LAPTOP-GUG8KQ9I:~/work/stack$ ./a.out
"pdes"   "name"   "epoch"   "a"   "e"   "i"   "om"   "w"   "ma"   "q"   "ad"   
1580   Betulia   2459600.5   2.197288160959855   .4871550690589618   52.07925829047207   62.2921305585828   159.5134530240992   16.62891169416756   1.126868095165017   3.267708226754692   
1620   Geographos   2459600.5   1.245689288381319   .3353623816094239   13.33753650294321   337.1849253204765   276.9463790166408   300.4925456829043   .8279319618844114   1.663446614878227   
1627   Ivar   2459600.5   1.86327342970777   .3967369932313492   8.451956512766827   133.120308337423   167.8035837640704   129.0289785125129   1.124043931637646   2.602502927777894   
1685   Toro   2459600.5   1.367465568905196   .435966790549019   9.382739662870495   274.2362441040706   127.2114688956593   300.0617970060148   .7712959936433091   1.963635144167082   
1862   Apollo   2459600.5   1.470502475713431   .5600430467767759   6.353083928279622   35.56898244993719   286.0386669340027   60.20237527657879   .6469577889220891   2.294047162504772   
1863   Antinous   2459600.5   2.25922922966352   .6059920366929147   18.39886422664638   346.4237098245764   268.0896471241496   244.0101430178307   .8901543074235589   3.628304151903481   
1864   Daedalus   2459600.5   1.460979692497998   .6144866009907846   22.21536437289675   6.613194571694206   325.6563726287792   196.1166696228387   .5632272471383416   2.358732137857654   
1865   Cerberus   2459600.5   1.079986459127503   .4669721847798676   16.09858904525619   212.8963846822369   325.2653260753237   170.2073771841984   .57566282277606   1.584310095478947   
1866   Sisyphus   2459600.5   1.893353802479725   .5383695942642949   41.20637430558688   63.47259682927852   293.0824330786623   331.1476239661798   .8740296840399557   2.912677920919495   
1915   Quetzalcoatl   2459600.5   2.543790754476287   .5706410666538692   20.40472660837776   162.9348721741076   347.8091351438147   41.39145147165023   1.092199284997688   3.995382223954886   
1916   Boreas   2459600.5   2.272324177667199   .4498393843780145   12.88297395642586   340.5981620510102   335.9167764123868   352.2401366045371   1.250143268478108   3.294505086856289   
1917   Cuyo   2459600.5   2.14981121226236   .5054666607865446   23.95922692157032   188.2869783127825   194.5115030151171   82.2843922810623   1.063153317478631   3.236469107046088   
1943   Anteros   2459600.5   1.430366783173011   .2560374828122278   8.706034969532251   246.3110706020363   338.3801329232052   173.8814283992249   1.064139272511169   1.796594293834852   
1980   Tezcatlipoca   2459600.5   1.709370985747121   .3648359123967504   26.8689695764886   246.560199388918   115.4661353995156   314.1597421163634   1.085731062537538   2.333010908956705   
1981   Midas   2459600.5   1.776435963774881   .6501354173857774   39.82986428861084   356.8569898560586   267.8286153975083   202.5329806814936   .621512027006993   2.931359900542769   
2059   Baboquivari   2459600.5   2.64324121274608   .531432311471031   11.02055447003622   200.6851159860844   192.4190577597405   181.8930083473287   1.23853742528094   4.04794500021122   
2061   Anza   2459600.5   2.264279343476608   .5360981217114927   3.800349706160866   207.3741353983842   157.0286649770264   354.1526556258232   1.050403440408666   3.478155246544549   
2062      2459600.5   .9669087478156669   .1827720931291991   18.9345273941421   108.5428491298942   148.0586126391113   21.46549438015371   .7901848121124645   1.143632683518869   
"1979 XB"      2444221.5   2.228085656329666   .7084495059291489   24.73412122397795   86.0555030947377   75.57989828051527   346.3183743701075   .6495994739350907   3.806571838724241   
594913   'Aylo'chaxnim   2459600.5   .5554326489245599   .1770230892406738   15.86839958719851   6.704982245275168   187.3289626591178   211.0111749229703   .4571082455468037   .6537570523023162   
ijb@LAPTOP-GUG8KQ9I:~/work/stack$ 
  • Related