How to read my csv file in Fortran?

Refresh

April 2019

Views

1.1k time

1

How to read following data in Fortran. I'm not able to read data in this file. I'm getting following error

severe (64): input conversion error, unit 18

Image              PC                Routine            Line        Source             
a.out              00000000004734AA  Unknown               Unknown  Unknown

This is my code:

        program dataread
        implicit none
        character*15 ::head_1,head_2,head_3,head_4,head_5,head_6
        character*15:: B,C, head_7,head_8,head_9,head_10
        real,dimension(1:71385,1:10)::A
        integer::i,j

        open(unit=18, file='Tws15thHourlyData.csv' , status='old',
     &  access ='sequential',form='formatted')!,recl=71781*10)

        read(18,*) head_1,head_2,head_3,head_4,head_5,head_6,
     &          head_7,head_8, head_9,head_10


       do i=2,71385
       read(18,300)(A(i,j),j=1,10)
300    format(I5,A17,2F9.6,A8,5F4.1)
       end do

        print*, head_1,head_2,head_3,head_4,head_5,head_6,
     &          head_7,head_8,   head_9,head_10
       do i=2,71385
       read(18,300)(A(i,j),j=1,10)
300    format(I5,A17,2F9.6,A8,5F4.1)
       end do

        print*, head_1,head_2,head_3,head_4,head_5,head_6,
     &          head_7,head_8,   head_9,head_10


        do i=2,71385
              print*, (A(i,j),j=1,10)
        end do
        close(18)
        open(unit=28,file='14data.txt')
        write(28, 100),((A(i,j),j=1,10),i=2,71385)
100     format(10(71385(I4,A15,2F9.6,A8,5F4.1,2x),/))
        end program

This data I'm trying to read

TWSCODE,DISTRICT,LATITUDE_DD,LONGITUDE_DD,RECORDED_DATE,HOUR,TEMPERATURE,HUMIDITY,WIND_SPEED,WIND_DIRECTION

109,KALABURAGI,17.463587,77.42,14-08-17,0,26.2,79.4,0,168
109,KALABURAGI,17.463587,77.42,14-08-17,0,26.2,80,0,25

109,KALABURAGI,17.463587,77.42,14-08-17,0,26.1,80.4,0,25
109,KALABURAGI,17.463587,77.42,14-08-17,0,25.9,81,0,25

109,KALABURAGI,17.463587,77.42,14-08-17,1,25.8,81.7,0,25
109,KALABURAGI,17.463587,77.42,14-08-17,1,25.9,82,0,287
109,KALABURAGI,17.463587,77.42,14-08-17,1,25.9,82.5,0,299
109,KALABURAGI,17.463587,77.42,14-08-17,1,25.8,82.8,0,286
109,KALABURAGI,17.463587,77.42,14-08-17,2,25.6,83.5,0,254
109,KALABURAGI,17.463587,77.42,14-08-17,2,25.6,83.9,0,292
109,KALABURAGI,17.463587,77.42,14-08-17,2,25.6,84,0,299
109,KALABURAGI,17.463587,77.42,14-08-17,2,25.6,84.2,0,309
109,KALABURAGI,17.463587,77.42,14-08-17,3,25.5,84.4,0,327
109,KALABURAGI,17.463587,77.42,14-08-17,3,25.4,84.8,0,315
109,KALABURAGI,17.463587,77.42,14-08-17,3,25.3,84.8,0,305
109,KALABURAGI,17.463587,77.42,14-08-17,3,25.2,84.8,0,306
109,KALABURAGI,17.463587,77.42,14-08-17,4,25.2,84.9,0,305
109,KALABURAGI,17.463587,77.42,14-08-17,4,25.2,85.1,0,306
109,KALABURAGI,17.463587,77.42,14-08-17,4,25.1,85.3,0,305
109,KALABURAGI,17.463587,77.42,14-08-17,4,25.1,85.4,0,305
109,KALABURAGI,17.463587,77.42,14-08-17,5,25.1,85.7,0,308

2 answers

4

I dislike @agentp's answer and flat out disagree with the comment that one should read the line as a string and mess about parsing it.

So I wrote this ...

As I pointed out in a comment above one of the errors (possibly the only one) in OP's code is using this statement, and format

       read(18,300)(A(i,j),j=1,10)
300    format(I5,A17,2F9.6,A8,5F4.1)

for trying to read a mixture of numbers and strings into an array of reals. That's never going to work out well. Take a step back and give the matters some thought. The input file contains some nicely-structured data, so why not define a nice structure for storing it ? First a type definition something like:

  TYPE :: met_record
     INTEGER :: TWSCODE
     CHARACTER(len=32) :: DISTRICT
     REAL :: LATITUDE_DD
     REAL :: LONGITUDE_DD
     CHARACTER(len=8) :: RECORDED_DATE
     INTEGER :: HOUR
     REAL :: TEMPERATURE
     REAL :: HUMIDITY
     REAL :: WIND_SPEED
     REAL :: WIND_DIRECTION
  END TYPE met_record

then an array of those

TYPE(met_record), DIMENSION(71385) :: weather_reports

Now reading the data is very easy indeed ...

do i = 1, 71385
    read(18,*) weather_reports(i)
end do

Look ! Not an explicit format in sight. Declare variables properly and let Fortran parse the input line.

Note:

  • I write relatively modern Fortran and have no truck with fixed-form source files.
  • I've not made any arrangements for reading the file header, there is already code for that.
  • Writing a met_record can be as simple as write(28,*) weather_reports(i)
0

this is one approach:

 integer,parameter :: n=71385
 character*15 :: strings(10,n)
 real :: a(7,n)
 integer :: tw(n)

..

 do i=1,n
   read(18,*)strings(:,i)
   read(strings(1,i),*)tw(i)
   read(strings(3:4,i),*)a(1:2,i)
   read(strings(6:10,i),*)a(3:7,i)
 end do

note as an aside that i transposed the arrays, so that the assignment is to contiguous memory positions.