Fortran90 で、CSV ファイルを読む

by I. Tamagawa (2010. Jan)
mod 2012. Jan
プログラム

CSV ファイルとは、「, 」で区切られたデータである。 ここでは、数値,数値,数値 と 「,」で区切られたデータが並んでいる CSV ファイルを読み出す時に、よく問題になる非数値データ ((例えば **** などの欠測記号)や、 カラム数が途中で変わっている場合の取扱いのサンプルをしめす。
2012年1月に、" " で囲まれた , を無視するように変更した。

プログラムの方針は、

  1. 一行単位で文字列として読み込む
  2. その行を、「,」で区切った文字列に分解する (サブルーチン devidecsv)
と言ったものである。後は、適当に read で文字列を数値に直すなどして使って欲しい。
!  add " treatment   2011.Jan.12
!
implicit none

integer, parameter  :: maxch=12
character(len=1024) :: buf, eachcol(maxch)
integer :: i, num

read(*, '(A)') buf

call devidecsv( buf, eachcol, maxch, num )

do i=1, num
 write(*,*) i, eachcol(i)(1:len_trim(eachcol(i)))
end do

end


subroutine devidecsv( buf, eachcol, maxch, num )
implicit none
integer   :: maxch, num
character(len=*) :: buf, eachcol(maxch)
integer :: i, j, prev, now, now1, ll
logical :: quote

quote = .FALSE.

ll = len_trim(buf)
prev=0; now=1; i=1
do j=1, ll
 if( buf(j:j) == '"' ) then
   quote = .NOT. quote
 end if
 if( quote .eqv. .FALSE. ) then
  if(buf(j:j) == ',') then
   now = j
   now1 = now -1
   if( now1 < prev+1 ) then
    eachcol(i) = ''
   else
    eachcol(i) = buf(prev+1:now1)
   end if
   i=i+1
   if( i > maxch ) then
     write(0,*) 'maxch is too small'
     stop
   end if
  prev=now
  end if
 end if
end do

if( prev < ll ) then
 eachcol(i) =  buf(prev+1:ll)
 num = i
else
 num=i-1
end if

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