- 締切済み
FORTRAN
まだ素人で。試行錯誤行っています。 現在、アメダス(一ヶ月平均)を読み取り、必要に応じて計算するようなプログラムを作っています。しかし、アメダスはバイナリのため、それを読めるようなプログラムが必要なのですが、 ===AMEDAS DATA FILE NAME OF THE MONTH (UNCOMPRESSED) 'Amd1976.01' ===INDEX FILE OF THE YEAR =========================== 'idx1976.01' ===OUT PUT FILE NAME============================== 'pre1976.01' ===SORT OF DATA, 50:presipitation, 60:wind direction, 70:wind speed, 80:insolation, 90:temperature, 67:wind direction+speed 50 ==BEGIN AND END OF STATION NUMBER===================== 10000 99000 で、指定するとそのファイルのバイナリが読めるようになっています。 それで順序は、 f77 ame_M2.for → ./a.exe → g95 1976search.f90 → ./a.exe で行っております。ame_M2.forはバイナリを読むプログラムです。1976search.f90は自分が作った、アメダスデータを必要に応じて計算をするプログラムです。ただ、これでは、1976年1月(一ヶ月分)のデータだけ呼んで計算する形なので、今、1976年1月から1999年12月までを一気に読んで計算させたいんです。どうすればよいでしょうか??今自分でも考え中なのですが、なにかアドバイス、案などありましたら教えてください。できれば、上の指定するファイルとバイナリを読むプログラムをほぼいじらないで、自分の作った計算プログラムだけで、行うことは可能なのでしょうか?? program main integer :: day,hour(1:24) integer :: i,j,n open(11, file='pre1976region.csv', status = 'unknown') open(10, file='pre1976.01', status='old') open(10, file='pre1976.02', status='old') do j = 1,30000000000000000 read(10,"(11x,I5,62x)", iostat=io) number if(io < 0) exit if (number == 53376 ) then do i = 1,40 select case(i) case(1:2,8,14,20,26,32,38,40) read(10,*) case default read(10, "(I2,1x,3(6I3,1x),6I3)") day, hour(1:24) where (hour(1:24) == 999) hour = 0 write(6,*) day,sum(hour) end select end do end if end do close(10) close(11) end program これが、僕が作ったプログラムでして、numberに地点番号を入力すればその地点の一月の毎日の雨の量がわかるようになっています。これをまず、20年近く読んで、たとえば東京をみたいとすると、その東京だけの20年分を見るようにしたいんです。 言葉足らずで、これを見せないと助言できないとかがありましたら、お教えください。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- A88No8
- ベストアンサー率52% (836/1606)
こんにちは >ファイルが違うのでcygwin上ではcd /d/1977に移るようにしなければいけませんよね 以下にファイル名にUNIX系OS上でのパスを含める例を書きます。 open(11, file='./path/pre1976region.csv', status = 'unknown') 応用として上記例で文字列定数'./path/pre1976region.csv'に文字列型変数を使えるならばパス(pathの部分は格納場所のパスに置換える)を含めたファイル名をあらかじめ準備しreadして宣言することも可能になるでしょう?ということをいいたかったのですが.. 混乱するということであれば一度データをREAD/WRITEして変換しアメダスから切り離した統合した独自データとしてファイルで持つ処理を実現した方が早道ではないですか? アメダスのデータをバイナリを含めて取り込むプログラムが出来ているのですから同じ路線で構築できるようにした方が質問者さんが速く目的にたどり着けそうです。 今はたどり着いてから全体をまとめることを構想することをお奨めします。 >例えば、ここでの配列とは?12ヶ月とかでいいんでしょうか?iは、01から12とあって01の表現はどうすれば?1と扱って大丈夫なのでしょうか? ヒントになるかどうかわからないけどfortranの場合は、ループ変数と文字列定数は分けた方が簡単かも.. INTEGER :: i CHARACTER(LEN=2)::month(1:12) = (/ '01','02','03','04','05','06','07','08','09','10','11','12' /) DO i = 1, 12 PRINT *, month(i) END DO END
- A88No8
- ベストアンサー率52% (836/1606)
こんにちは >現在1976というファイルに1976.01、1976.02、1977というファイルに1977.01、1977.02という感じでアメダスデータがある状態です。まずそれをひとつにまとめるということでしょうか? アメダスデータは、どんどん増えていくという前提であらかじめ読むべきファイル名をテキストファイルに定義しておき、実行時にファイル名を取得して読み込んでいくような作りにして置けば自由度が高いかなというアイデアです。 しかし、いつも20年近く前からの開始のデータで開始時期を変更はないならば、一つのファイルににまとめてしまうのも良いアイデアだと思います。 あと新たに増えたデータファイルはどうするか? (1)20年近く前からの開始のデータファイルに新データをアペンドする処理を別に実行してから処理を回す。 (2)20年近く前からの開始のデータファイルと新データファイルをテキスト形式の定義ファイルにファイル名を定義し、それを元にファイルを読み込んで処理を回す。 (1)か(2)のいずれかですよね。 >バイナリを読むファイルはどうすうればよいでしょう? すいませんが意味が分かりません。データファイルを読み込んで立派に処理を実現されているので解決済みの問題と受け止めています。 バイナリの場合カンマや空白文字で区切られていること自体考えられないので入力ファイルのデータ構造が判らないと何ともいえないですね。 外していたらごめんなさい。
- A88No8
- ベストアンサー率52% (836/1606)
こんにちは 考え方としてファイル名をプログラムの中に埋め込まず、特定のイニシャルファイルを作ってその中にテキストデータとしてファイル名を登録しておき、ファイル名を読み込み、そのファイルをオープンしデータを読み込みながら繰返し集計したらいかがかと思います。 質問者さんに貼ったプログラムをメンテナンスできる力があれば、上記は容易だと思いました。
お礼
ありがとうございます。ちょっとまだ未熟者で少しわからないとこがあるのですが、現在1976というファイルに1976.01、1976.02、1977というファイルに1977.01、1977.02という感じでアメダスデータがある状態です。まずそれをひとつにまとめるということでしょうか?バイナリを読むファイルはどうすうればよいでしょう?すいませんが、もう少し教えてもらえないでしょうか?お願いします。
お礼
ありがとうございます。ちょっと混乱しています。テキストファイル?テキストデータ?それに1976ファイル、1977ファイルを読むようにプログラムを書くということですよね?現在cygwinで行っていますが、1976ファイルを読み終わると、ファイルが違うのでcygwin上ではcd /d/1977に移るようにしなければいけませんよね?そいうこともテキストデータ内のプログラムで行えるのでしょうか?バイナリのほうですが、現在、毎回一ヶ月ごとにAme.inというテキストデータで読む月を指定し、それを読んでバイナリを読めるように直すプログラムをコンパイルし実行し、できたファイルを計算するのですが、その実行も含めてテキストデータのプログラムに定義する(できる)ということでしょうか?それができても少なくとも、一ヶ月読んで次の一ヶ月には、cygwin上でenterキーをコンパイル、実行するために2回押す必要がありますよね?言葉だとうまく表現できなくてすいません。なんとなくわかってきてるのですが。うまく書けません。人の質問を調べていると、例えばwrite(配列,'1976.''i')k、とメモリーの配列に書き込み、このiにdo パラメータのkを当てれば、1重のループで順次開けると。例えば、ここでの配列とは?12ヶ月とかでいいんでしょうか?iは、01から12とあって01の表現はどうすれば?1と扱って大丈夫なのでしょうか?iにdoパラメターのkを当てるとは?do i=1,kということでしょうか? すいません。話がずれてしまい。再度こたえれるところだけでもかまいませんので、お教えいただけるとありがたいです。すいません、お願いします。