2016-09-08 10 views
0

反応のリストとその反応タイプを読むためにFortranコードを書いています。リストには、このようなファイルの名前reactions.rxである:Fortranの行読みバグ

H2O  O1D  OH  OH    2BODY     . 
       . 
       . (Same format continued) 
       . 
CH3C2H HV  C3H3  H     PHOTO 
CH3C2H HV  C3H2  H2    PHOTO 
CH3C2H HV  CH3  C2H    PHOTO 
CH2CCH2 HV  C3H3  H     PHOTO 
CH2CCH2 HV  C3H2  H2    PHOTO 
CH2CCH2 HV  C2H2  CH23    PHOTO 
C2H6  HV  CH23  CH23  H2  PHOTO 
C2H6  HV  CH4  CH21    PHOTO 
C2H6  HV  C2H2  H2  H2  PHOTO 
C2H6  HV  C2H4  H   H  PHOTO 
C2H6  HV  C2H4  H2    PHOTO 
C2H6  HV  CH3  CH3    PHOTO 
C2H  C2H2  HCAER  H     2BODY 
C2H  CH2CCH2 HCAER2 H     2BODY 

目標は、それがラベルの写真を持っている一番左の列に指定された種の最初の発生を発見するようにコードを記述することで、その行にその種が含まれなくなるか、PHOTOになるまでファイルを読み続ける。これまで

私のコード:(貧しいフォーマットを許して)少し明確にするため

AT SPECIES: H2O 
ON LINE: H2O  HV  H   OH     PHOTO 
NEXT LINE: O3  HV  O2  O1D     PHOTP     0 
AT SPECIES: CO2 
ON LINE: CO2  HV  CO  O     PHOTO 
NEXT LINE: CO2  HV  CO  O1D     PHOTO     0 
AT SPECIES: CO2 
ON LINE: CO2  HV  CO  O1D     PHOTO 
NEXT LINE: CO  OH  CO2  H     WEIRD     0 
AT SPECIES: H2CO 
ON LINE: H2CO  HV  H2  CO     PHOTO 
NEXT LINE: H2CO  HV  HCO  H     PHOTO     0 
AT SPECIES: H2CO 
ON LINE: H2CO  HV  HCO  H     PHOTO 
NEXT LINE: HCO  HV  H   CO     2BODY     0 
AT SPECIES: CH4 
ON LINE: CH4  HV  CH21  H2     PHOTO 
NEXT LINE: CH4  HV  CH3  H     PHOTO     0 
AT SPECIES: CH4 
ON LINE: CH4  HV  CH3  H     PHOTO 
NEXT LINE: CH4  HV  CH23  H   H   PHOTO     0 
AT SPECIES: CH4 
ON LINE: CH4  HV  CH23  H   H   PHOTO 
NEXT LINE: C   OH  CO  H     2BODY     0 
AT SPECIES: CH 
ON LINE: CH  HV  C   H     PHOTO 
NEXT LINE: CH  S   CS  H     2BODY     0 
AT SPECIES: CH2CO 
ON LINE: CH2CO  HV  CH23  CO     PHOTO 
NEXT LINE: CH23  CO  CH2CO       WEIRD     0 
AT SPECIES: C2H2 
ON LINE: C2H2  HV  C2H  H     PHOTO 
NEXT LINE: C2H2  HV  C2  H2     PHOTO     0 
AT SPECIES: C2H2 
ON LINE: C2H2  HV  C2  H2     PHOTO 
NEXT LINE: C2H2  OH  CO  CH3     2BODY     0 
AT SPECIES: C2H4 
ON LINE: C2H4  HV  C2H2  H2     PHOTO 
NEXT LINE: C2H4  HV  C2H2  H   H   PHOTO     0 
AT SPECIES: C2H4 
ON LINE: C2H4  HV  C2H2  H   H   PHOTO 
NEXT LINE: CH23  CH3  C2H4  H     2BODY     0 
AT SPECIES: CH3CHO 
ON LINE: CH3CHO HV  CH3  HCO     PHOTO 
NEXT LINE: CH3CHO HV  CH4  CO     PHOTO     0 
AT SPECIES: CH3CHO 
ON LINE: CH3CHO HV  CH4  CO     PHOTO 
NEXT LINE: C2H5  CH3  C3H8       WEIRD     0 
AT SPECIES: C3H8 
ON LINE: C3H8  HV  C3H6  H2     PHOTO 
NEXT LINE: C3H8  HV  C2H6  CH21    PHOTO     0 
AT SPECIES: C3H8 
ON LINE: C3H8  HV  C2H6  CH21    PHOTO 
NEXT LINE: C3H8  HV  C2H4  CH4     PHOTO     0 
AT SPECIES: C3H8 
ON LINE: C3H8  HV  C2H4  CH4     PHOTO 
NEXT LINE: C3H8  HV  C2H5  CH3     PHOTO     0 
AT SPECIES: C3H8 
ON LINE: C3H8  HV  C2H5  CH3     PHOTO 
NEXT LINE: C2H  C3H8  C2H2  C3H7    2BODY     0 
AT SPECIES: C3H6 
ON LINE: C3H6  HV  C2H2  CH3  H   PHOTO 
NEXT LINE: C3H6  HV  CH2CCH2 H2     PHOTO     0 
AT SPECIES: C3H6 
ON LINE: C3H6  HV  CH2CCH2 H2     PHOTO 
NEXT LINE: C3H6  HV  C2H4  CH23    PHOTO     0 
AT SPECIES: C3H6 
ON LINE: C3H6  HV  C2H4  CH23    PHOTO 
NEXT LINE: C3H6  HV  C2H  CH4  H   PHOTO     0 
AT SPECIES: C3H6 
ON LINE: C3H6  HV  C2H  CH4  H   PHOTO 
NEXT LINE: C2H5CHO HV  C2H5  HCO     PHOTO     0 
AT SPECIES: C2H5CHO 
ON LINE: C2H5CHO HV  C2H5  HCO     PHOTO 
NEXT LINE: H2O  O1D  OH  OH     2BODY     0 
AT SPECIES: C3H3 
ON LINE: C3H3  HV  C3H2  H     PHOTO 
NEXT LINE: CH3C2H HV  C3H3  H     PHOTO     0 
AT SPECIES: CH3C2H 
ON LINE: CH3C2H HV  C3H3  H     PHOTO 
NEXT LINE: H2O  O1D  OH  OH     2BODY     0 
AT SPECIES: CH2CCH2 
ON LINE: CH2CCH2 HV  C3H3  H     PHOTO 
NEXT LINE: CH2CCH2 HV  C3H2  H2     PHOTO     0 
AT SPECIES: CH2CCH2 
ON LINE: CH2CCH2 HV  C3H2  H2     PHOTO 
NEXT LINE: CH2CCH2 HV  C2H2  CH23    PHOTO     0 
AT SPECIES: CH2CCH2 
ON LINE: CH2CCH2 HV  C2H2  CH23    PHOTO 
NEXT LINE: C2H6  HV  CH23  CH23  H2  PHOTO     0 
AT SPECIES: C2H6 
ON LINE: C2H6  HV  CH23  CH23  H2  PHOTO 
NEXT LINE: H2O  O1D  OH  OH     2BODY     0 

、種AT::私はどの種告げるこのコードの

! reactions.rx is opened earlier as file 12 
667 FORMAT(A10, A10, A10, A10, A8, A5) 

     stat = 0 
     ! Reads until a line is found in reactions.rx with reactant1 == species 
     ! and label beginning with "PHOT" 
     do while((trim(reac1).ne.trim(species).OR.label(1:4).ne.'PHOT') 
    & .AND.stat == 0) 
     READ(12,667,IOSTAT=stat) reac1,reac2,prod1,prod2,prod3,label 
     end do 

     if(stat.ne.0) then 
     print*, " *** Species not in reactions.rx!!!! *** " 
     STOP 
     endif 

    ! reac1...prod3,label hold the first line of matching info 
    ! Does some work ... 

    ! Continue reading the file until the line is no longer about a PHOT 
    ! reaction beginning with species 
    do while(trim(reac1).eq.trim(species).AND. 
    & label(1:4).eq.'PHOT') 
     if(label(5:5).ne.'O') then 
     ! Does some work ...  
     else 
     ! Does some work ... 
     ! The following print statements are for testing purposes 
     print*, "AT SPECIES: ", species 
     print*, "ON LINE: ", reac1,reac2,prod1,prod2,prod3,label 
     endif 
     stat = 0  
     READ(12, 667, IOSTAT=stat) reac1,reac2,prod1,prod2,prod3, 
    &  label 
     print*, "NEXT LINE: ",reac1,reac2,prod1,prod2,prod3,label, 
    &  stat   
     if(stat.ne.0) then 
     label = 'DONE ' !breaks while 
     endif 
    enddo 
    close(12) 

私は出力を得ますreac1と一致します。 ON LINEは、要件(種およびPHOT)に一致するライン情報を出力します。 NEXT LINEは、次に読み込まれる行を出力します。

私のバグはCH3C2H種に最初に出現します。出力から見ることができるように、CH3C2Hの1つの反応ラインが読み込まれます(出力の下から15ラインアップ)。しかし、NEXT LINEは "H2O O1D OH OH 2BODOD"と表示されます。 reactions.rxの次の行(読み込みになるはずです)は "CH3C2H HV C3H2 H2 PHOTO"であることがはっきりと分かります。これは私が興味を持っている反応ですが、なんらかの理由で、読み込まれた行は代わりに反応の最初の行です。同じ問題がC2H6(最終出力)に発生します。この種については、5行をreacts.rxから読み込むべきですが、最初の行の次の行がH2O .... 2BODYになった後にもう一度読み込んでください。 H2Oラインはdoループを正当に終了させます。私の問題は、なぜこの2つのケースで間違ったラインが読み取られるのか理解できないことです。

「!いくつかの作業...」とコメントしている場合がありますが、私が興味を持っている実際の印刷と読み込み文には、他のコードはありません。このため、変数/ストレージの問題ではないと私は思っています。ループや実際の読み込みでエラーが発生しているようです。私は正しいファイル(reacts.rx)が読み込まれていると確信しています。私もそれに変更を加え、コード内にすべてのものを印刷して、それが読み込まれているファイルであることを確認しました。

私の人生にとっては、なぜこのコードが上記の2つ以外の他のすべての種に対しても意図されているものなので、このバグが起こる理由を理解できません。人々が提供できるあらゆる助けや提案は非常に高く評価されるでしょう。

Windows 10マシンでgfortran 5.3.0でコンパイルしています。

+1

*出力からわかるように*実際はありません。なぜあなたの入力ファイルのように整理された素敵なテーブルを書くのではなく、それは私が(どこにいても)物事がどこでどのようにうまくいかないかを見るのがずっと楽になります。 –

+0

私はそう思います... '!いくつかはファイルを再オープンするか、ユニット「12」を再配置しますか?デバッガで実行をトレースするとどうなりますか? – IanH

+0

@HighPerformanceMarkあなたが正しいです。出力を実際にフォーマットするには多少時間がかかるでしょう。残りの日には他の義務がありますが、私は明日私の投稿を更新しようとします。 – WhS4

答えて

1

あなたの質問にコメントの「コードの私のバージョン」と尋ねました。 私がやったことは、私はそのように最初に、ここにあなたのコードは最小限に修正、だ

CALL READ_REACTIONS(species) 

で呼び出すサブルーチンにコードを有効にすることです:

 SUBROUTINE READ_REACTIONS(species) 
     implicit none 
     character(len=10) :: species 
     character(len=10) :: reac1, reac2, prod1, prod2 
     character(len=8) :: prod3 
     character(len=5) :: label 
     integer stat 

     PRINT *, "Searching for species " // species 

     OPEN(12, file="reactions.rx", action="READ") 
    667 FORMAT(A10, A10, A10, A10, A8, A5) 

     stat = 0 
     ! Reads until a line is found in reactions.rx with reactant1 == species 
     ! and label beginning with "PHOT" 
     do while((trim(reac1).ne.trim(species).OR.label(1:4).ne.'PHOT') 
    & .AND.stat == 0) 
     READ(12,667,IOSTAT=stat) reac1,reac2,prod1,prod2,prod3,label 
     end do 

     if(stat.ne.0) then 
     print*, " *** Species not in reactions.rx!!!! *** " 
     GOTO 999 ! < You had a STOP here, but I'd rather make a clean 
       ! exit including the CLOSE 
     endif 

     ! reac1...prod3,label hold the first line of matching info 
     ! Does some work ... 

     ! Continue reading the file until the line is no longer about a PHOT 
     ! reaction beginning with species 
     do while(trim(reac1).eq.trim(species).AND. 
    & label(1:4).eq.'PHOT') 
     if(label(5:5).ne.'O') then 
      ! Does some work ... 
     else 
      ! Does some work ... 
      ! The following print statements are for testing purposes 
      print*, "AT SPECIES: ", species 
      print*, "ON LINE: ", reac1,reac2,prod1,prod2,prod3,label 
     endif 
     stat = 0 
     READ(12, 667, IOSTAT=stat) reac1,reac2,prod1,prod2,prod3, 
    &  label 
     print*, "NEXT LINE: ",reac1,reac2,prod1,prod2,prod3,label, 
    &  stat 
     if(stat.ne.0) then 
      label = 'DONE ' !breaks while 
     endif 
     enddo 
999 CONTINUE ! <-- added label for the clean exit if species not found. 
     close(12) 
     END SUBROUTINE READ_REACTIONS 

あなたが見ることができるように、唯一の私は宣言ブロックとOPENステートメントを追加し、ファイルを閉じる直前にSTOPGOTOに変更しました。

私はあなたの完全なreactions.rxを持っていませんが、提供したスニペットでうまくいきます。

read_reactionsの独自のバージョンを作成しましたが、これは少し読みやすいと思います。私は明示的なインターフェイスを宣言する必要がないように、モジュール全体を包みました。実際のコードでは、実際にはエラー処理を改善していますが、この投稿はすでに長すぎます。

module mod_read_reactions 

    implicit none 
    character(len=*), parameter :: fmt = "(4(A10), A8, A5)" 
    character(len=*), parameter :: file_name = 'reactions.rx' 
contains 
    subroutine read_reactions(species) 
    implicit none 
    character(len=10), intent(in) :: species 
    integer :: iounit, ios 
    character(len=200) :: iomsg 
    character(len=10) :: reac1, reac2, prod1, prod2 
    character(len=8) :: prod3 
    character(len=5) :: label 

    open(newunit=iounit, file=file_name, iostat=ios, & 
      iomsg=iomsg, status="old", action="read") 
    if (ios /= 0) stop "Error opening file " ! Suggest better error handling 

    searchloop : do 
     read(iounit, fmt, iostat=ios, iomsg=iomsg) & 
      reac1, reac2, prod1, prod2, prod3, label 
     if (ios /= 0) then 
     print *, "Species " // trim(species) // " not found." 
     goto 999 
     end if 

     if (reac1 == species .and. label == "PHOTO") exit searchloop 
    end do searchloop 

    do while (ios == 0 .and. reac1 == species .and. label == 'PHOTO') 
     ! When we come in here, we should already have the first match, so we can 
     ! immediately act upon it (in this case just print it out) 
     print *, reac1, reac2, prod1, prod2, prod3, label 

     ! Now read the next line. 
     read(iounit, fmt, iostat=ios, iomsg=iomsg) & 
      reac1, reac2, prod1, prod2, prod3, label 
    end do 

999 continue 
    close(iounit) 
    end subroutine read_reactions 

end module mod_read_reactions 

このコードは新しい種のリクエストごとにファイルを開いたままにしておきますが、スマートではありません。

関連する問題