Fortran77 (古い!) で、CSV ファイルを読む

by I. Tamagawa (2005. Jun)
プログラム

CSV ファイルとは、「, 」で区切られたデータである。 ここでは、数値,数値,数値 と 「,」で区切られたデータが並んでいる CSV ファイルを F77 で読み出す時に、よく問題になる非数値データ ((例えば **** などの欠測記号)の取扱いのサンプルをしめす。

プログラムの方針は、

  1. 一行単位で文字列として読み込む
  2. その行を、「,」で区切った文字列に分解する
  3. 分解した文字列を数値に変換する(readを使う)際に、例外処理として非数値データを処理する
と言ったものである。ASCII 以外の文字がある場合や、上記以外のパターンの CSV データにてついては、簡単のために考慮していない。あくまで、サンプルとして 使って欲しい。
      parameter(num_x=10, num_data=1000)
      integer num, ndata, err_read
      character*1024 line
      real x(num_x, num_data)

      ndata = 1
      err_read = 0

       do while( (ndata.le.num_data).and.(err_read.eq.0) )
       read(*,'(A)', err=999, end=999) line
       call line2data( line, num_x,x, num,ndata)
        write(*,*) num, (x(i,ndata), i=1,num)
       goto 998
  999 err_read=-1
  998 continue
       end do

      do i=1,(ndata-1)
      write(*,*), i, (x(j,i),j=1,num)
      end do
      stop
      end


      subroutine line2data( line, num_x, x, num,ndata)
      character*1024 line
      integer num, num_x,ndata
      real x(num_x,ndata)
      integer i, j, k, ch, n_line
      character*1024  buf, delim, buf2

      delim=','

      j=1
      ch=1

      do i=1,len(line)
      if(line(i:i) .eq. delim(1:1)) then
	      call conv_data( buf,1,j-1, x(ch,ndata) )
              ch = ch+1
	      j=1
      else
         buf(j:j) = line(i:i)
	 j=j+1
      endif
      end do
      call conv_data( buf,1,j-1, x(ch,ndata) )
      num = ch
       ndata = ndata +1
      end



      subroutine conv_data( buf, i1, i2, xx)
      character*1024 buf
      real xx
      parameter (xmiss=-9999)

C	write(*,*) 'buf=', buf(i1:i2)
        read(buf(i1:i2), *, err=900) xx
	      goto 910
  900         xx = xmiss
  910         continue
      end

サンプルソフトのページへ
研究室のページへ