みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

fortranについての質問です。

fortranについての質問です。
このFortranは、頭にそれぞれ14161~14163とつく33個のファイル(1/1~12/31,欠損地あり1年分)を読んでいき、例えば1/1、1/2…と365日分の33年の平均値を導くはずなのですが、下のようなエラーがでます。おそらく、14161が2008までないからではないかと思うのですが、現在勉強中なので、なにかアドバイス、おかしいところ修正できるところがありましたらお願いします。

program sapporo_kikouchi

   INTEGER :: sum, no, point
INTEGER :: year, mon, day, data
INTEGER :: doy
REAL,dimension(365) :: temp, ndata
REAL :: lon, lat
CHARACTER*4 yyyy
CHARACTER*5 sssss
ndata(:)=0.0
temp(:)=0.0

do ispot=14161,14163
write(sssss,"(i5)") ispot
do iwork=1976, 2008
write(yyyy,"(i4.4)") iwork

open(50, file=''//sssss//'_temp'//yyyy//'.csv', status='old')
! write(6,*) ispot iwork

   do i = 1,366

read(50,*,iostat=io) id,year,mon,day,lon,lat,data
if(io < 0) exit
if(mon==2 .AND. day==29) then
cycle
endif

call date2doy(year,mon,day,doy)
temp(doy) = temp(doy) + data/10.0
ndata(doy) = ndata(doy) + 1

end do

close(50)
enddo !!! end of year loop
enddo

do i=1,365
if( ndata(i) == 0 ) then
temp(i) = -99999.9
else
temp(i)=temp(i)/ndata(i)
endif

write(6,*) i, temp(i), ndata(i)
enddo

stop
end program

subroutine date2doy(iy,im,id,idoy)
INTEGER,dimension(12) :: nday
INTEGER :: uruu !!uruu=1: うるう年、uruu=0: 通常の年

uruu=0
DATA nday /31,28,31,30,31,30,31,31,30,31,30,31/

if(mod(iy,4)==0 .AND. mod(iy,100)/=0) then
uruu=1
endif
if(mod(iy,1000)==0) then
uruu=1
endif


!! うるう年も無視する
itotal = 0
if( im /= 1 )then
do m=1, im-1
itotal = itotal + nday(m)
enddo
endif
idoy = id + itotal

! write(6,*) iy,im,id, idoy


return
end
------------------------------------------------------------------------------
At line 18 of file kikouchi.f90 file: "14161_temp1993.csv"
Traceback: not available, compile with -ftrace=frame or -ftrace=full
Fortran runtime error: 指定されたファイルが見つかりません。
-------------------------------------------------------------------------------

投稿日時 - 2010-08-08 18:06:06

QNo.6095667

困ってます

質問者が選んだベストアンサー

> 一度、iostat=ioをOPEN文に指定せずif (io < 0) cycleと書いたときは、同じようなエラーがでたのですが

それはそうでしょう。OPEN文を実行したときのステータスをどの変数に設定すればよいのか教えてもいないのに,ioという変数を見ても仕方がありません。

> if文のなか(io < 0)でも(io /= 0)でも回りました。あまり差はないんですかね?

正常に開けたときは0になって,そうでない場合は正の整数が返ります。負の値が返るのはあなたの使っているシステムの拡張機能ではないですか?なんにせよエラーの原因に興味がないときには0であるかどうかだけを判定すれば十分です。エラーの原因を知りたければ値がどうなっているかを調べます。

> ただ、今回回ったものの全て欠損値として出力されてしまっています。

本当にファイルの中身はあるのですか?また中身があったとしてもファイルは正常に読めているのですか?そういうことを確認すべきですね。デバッガを使うとか,
read(50,*,iostat=io) id,year,mon,day,lon,lat,data
の次の行に
print*,id,year,mon,day,lon,lat,data
とでも書いて確認してください。

投稿日時 - 2010-08-09 12:03:37

お礼

ありがとうございました。

できました。違うチェックのためにファイルを一度違うファイルのなかに隠しておいたせいでした。
本当に助かりました。

また、おそらくFRTRANについて質問すると思いますが、もし見かえることがありましたら、ぜひご教授いただけるとうれしいです。

今回はありがとうございました。

投稿日時 - 2010-08-09 17:10:11

ANo.3

このQ&Aは役に立ちましたか?

6人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

うるう年であるのは以下の条件です。
if(mod(iy,4)==0) uruu=1
if(mod(iy,100)/=0) uruu=0
if(mod(iy,400)==0) uruu=1
もし1976年から2008年まで限定で良いのなら
if(mod(iy,4)==0) uruu=1
だけで済みます。

エラーメッセージとして14161_temp1993.csvがないといわれています。
欠損値を除いた平均値を導きたいということなら
open(50, file=''//sssss//'_temp'//yyyy//'.csv', status='old')
でエラーとなった時にスキップするよう
open(50, file=''//sssss//'_temp'//yyyy//'.csv', status='old', iostat=io)
if(io /= 0) cycle
とでもしておけばいいんじゃないかな。

投稿日時 - 2010-08-09 10:41:22

お礼

ありがとうございました。

一度、iostat=ioをOPEN文に指定せず

if (io < 0) cycle

と書いたときは、同じようなエラーがでたのですが、今回回りました。
確かめたところ、指定しないとだめなんですね。
またif文のなか(io < 0)でも(io /= 0)でも回りました。あまり差はないんですかね?
ただ、今回回ったものの全て欠損値として出力されてしまっています。

1 -99999.9 0.
2 -99999.9 0.

365 -99999.9 0.

となっています。まだ修正しなければいけないところがあるようです。
なにかアドバイスあるでしょうか?

投稿日時 - 2010-08-09 11:01:40

ANo.1

エラーの原因は分かっているようですが、どのように処理したいのでしょうか?
それからdate2doyでは閏年の判定らしきものをやっているが、その判定が間違っている上に、せっかくの判定を使っていないのはどうして?

投稿日時 - 2010-08-08 21:22:40

お礼

ありがとうございます。

うるう年のところ間違っていますか?どこが違いますか?確かに今回は使用しません。が、今後違う視点で見る必要が出てくるので、書いときました。先頭に!つけます。

また、今回の最終的な目標は、上にも書きましたが、「1/1、1/2…と365日分の33年の平均値を導く」ということです。欠損値があるため、欠損値を除いた平均値を導きたいのです。
どういう処理というのはどういうことでしょうか?
画面に出力されるのは、1976~1992年までしか出力されず、

write(6,*) i, temp(i), ndata(i)

の部分が出力されていないんです。
このプログラムを作ったときは、14161_temp[1976-2008]が33個、ディレクトリにあった際は回ったはずなのですが。

投稿日時 - 2010-08-09 09:31:09