0

I am trying to read a CSV file with the following structure:

12,30,2010,23,00,01,125550,1,10643,125550,125575,4665142,0,0
12,30,2010,23,00,44,125550,1,10644,125525,125550,4665188,0,0
12,30,2010,23,01,55,125575,1,10645,125550,125575,4665287,0,0
12,30,2010,23,02,20,125550,1,10646,125550,125575,4665299,0,0

The data is presented in the standard input.

I have been suggested to look at these SO posts:

Using do loop in a Fortran 90 program to read different number of lines for n frames?

Read a file with an unknown number rows in Fortran

Both uses files, not the standard input.

I have modified my code and added the iostat check:

program file_parser

        implicit none

        ! -------------------
        ! TYPE DEFINITION
        ! -------------------
        type :: type1_record
                integer :: month
                integer :: day
                integer :: year
                integer :: hour
                integer :: minute
                integer :: second
                integer :: field1
                integer :: field2
                integer :: field3
                integer :: field4
                integer :: field5
                integer :: field6
                integer :: field7
                integer :: field8
        end type

        ! -------------------
        ! VARIABLE DEFINITION
        ! -------------------
        integer :: i, io_result
        type(type1_record), dimension(10000) :: input_data
        i = 0
        do 
                read(*,*,iostat=io_result) input_data(i)
                if (io_result /= 0) exit
                i = i + 1        
        end do

        do i = 1, 3
                write(*,*) input_data(i)
        end do


end program

However, when I run the program I still get Segmentation fault (core dumped):

$cat test_data.txt | ./a.out
Segmentation fault (core dumped)

Note: test_data.txt contains the data presented at the beginning.

What I am doing wrong with respect of the SO posts that have been previously suggested?

I am using flang and trying to stick to Fortran 95 standard.

Ian Bush
  • 6,996
  • 1
  • 21
  • 27
M.E.
  • 4,955
  • 4
  • 49
  • 128
  • Please have a look at the `end=` etc. for the read statement. – albert May 18 '21 at 07:47
  • We have many questions about reading a CSV. One of them might be a duplicate. Also, which flang do you use? There are multiple project using this name. – Vladimir F Героям слава May 18 '21 at 07:49
  • 1
    `read ([unit=]u, [fmt=]fmt [,iostat=ios][, err=error-label] [,end=end-label]) [list]`. For example, `read(unit = 123,*, iostat = iostat) input_data(i); if (iostat < 0) write(*,*) "end of file"` – Scientist May 18 '21 at 07:52
  • 1
    You claim that the links only use files, not standard input. But there is not standard input as a specific entity in Fortran! There is a file, that is pre/connected, and that file is what you call "standard input". Yes, you cannot rewind it, but you definitely can use the other method from the links. – Vladimir F Героям слава May 18 '21 at 08:07
  • 1
    Neither of the duplicate answers mention iostat_end in the iso_fortran_env intrinsic module - I would look that up as well – Ian Bush May 18 '21 at 08:09
  • @IanBush However, the OP explicitly wants the Fortran 95 standard. But the linked answers certainly can be updated. – Vladimir F Героям слава May 18 '21 at 08:09
  • @VladimirF What is the other method from the links?. Bear in mind that what it is obvious to you it might not be for newcomers to the language. – M.E. May 18 '21 at 08:10
  • @M.E. You say that you included the iostat but did not say how. I will check if a more appropriate method is described elsewhere, and if not, I will reopen. But I am sure it is, we have many questions about reading a file with unknown number of lines. – Vladimir F Героям слава May 18 '21 at 08:12
  • Actually I just found that the iostat check works. But the program fails at the end, after writing out the three records. If I type `write(*,*) "TEST"` at the end I see that displayed. But then it comes the `Segmentation fault (core dumped)` – M.E. May 18 '21 at 08:13
  • The complete code including the iostat check can be in the second question: https://stackoverflow.com/questions/67582219/how-to-detect-end-of-data-in-standard-input-in-fortran-95 – M.E. May 18 '21 at 08:15
  • @VladimirF Just because they are limited to a quarter of a century old environment now (but they mentioned flang) doesn't mean it wouldn't be good to learn a better way to do it once they get access to a more modern one. – Ian Bush May 18 '21 at 08:16
  • The iostat check works, it was related to using 0 base index for the array as spoted in the other post https://stackoverflow.com/questions/67582219/how-to-detect-end-of-data-in-standard-input-in-fortran-95. I am wondering why the program continues execution after this has happened. Is it like the Segmentation fault is reserved until the end of the execution or is it reported with delay so the rest of the code is actually executed? – M.E. May 18 '21 at 08:22
  • 1
    @M.E. Typically by default Fortran compilers try to make the code run as fast as possible - and this means omitting checks for things like accessing an array out of bounds. However all respectable compilers include a flag to include such checks, you will have to check your own documentation but with gfortran it is -fcheck=all, and you probably want -g as well. This will find such errors, but it will make the program run typically 3-4 times slower - so once you are sure the program is right (but not before!) remove it, but until then I strongly suggest you use it. – Ian Bush May 18 '21 at 08:53

0 Answers0