Ajay
Ajay

Reputation: 320

How to read my csv file in Fortran?

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

Upvotes: 4

Views: 12082

Answers (2)

agentp
agentp

Reputation: 6989

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.

Upvotes: 1

High Performance Mark
High Performance Mark

Reputation: 78316

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)

Upvotes: 11

Related Questions