2016-09-08 4 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의 한 반응 라인은 반드시 읽어야합니다 (출력 하단에서 15 라인 위로). 그러나 NEXT LINE은 "H2O O1D OH OH 2BODY"로 인쇄됩니다. reactions.rx의 다음 줄은 꽤 분명합니다. "CH3C2H HV C3H2 H2 PHOTO". 이것은 제가 관심을 갖는 반응이지만, 어떤 이유로 든 읽은 줄은 반응의 첫 줄입니다. C2H6에서도 동일한 문제가 발생합니다 (마지막 출력). 이 종에 대해서는 5 줄의 더 많은 줄이 reacts.rx에서 읽혀 야하지만 첫 번째 줄 다음 줄이 H2O .... 2BODY가됩니다. H2O 라인은 do 루프를 정당하게 끝냅니다. 문제점은이 두 가지 경우에 잘못된 라인을 읽는 이유를 이해할 수 없다는 것입니다.

일부 경우에는 "! 어떤 작업을 수행합니다 ..."코드가 더 많습니다. 실제 인쇄물을보고 내가 읽은 문장을 읽을 수 있으므로 다른 코드는 없습니다. 이 때문에 변수/저장 문제가 아니라고 생각합니다. 루프 또는 실제 읽기에서 오류가있는 것 같습니다. 정확한 파일 (reactions.rx)이 읽히고 있다고 확신합니다. 나는 코드를 변경하여 코드에서 모든 것을 인쇄하여 파일이 읽혔는지 확인했습니다.

필자는이 버그가 왜 발생하는지 알아낼 수 없습니다. 특히 코드가 위에 설명 된 두 가지를 제외하고 다른 모든 종에 대해 수행하려는 의도와 정확히 동일하기 때문입니다. 사람들이 제공 할 수있는 모든 도움이나 제안은 대단히 감사하겠습니다.

Windows 10 시스템에서 gfortran 5.3.0으로 컴파일 중입니다.

+1

* 출력에서 ​​볼 수 있듯이 *별로 없습니다. 왜 입력 파일처럼 조직 된 깔끔한 테이블을 작성하지 않습니까? 그것은 나를 위해 (심지어 당신도) 일이 어디서 그리고 어떻게 잘못되는지보기가 훨씬 쉬울 것입니다. –

+0

나는 추측한다. .. '! 일부는 파일을 다시 열거 나 '12'단위의 위치를 ​​변경합니다. 디버거에서 실행을 추적하면 어떻게됩니까? – IanH

+0

@HighPerformanceMark 맞습니다. 실제로 출력을 포맷하려면 시간이 좀 걸릴 것입니다. 나는 나의 남은 시간 동안 다른 의무를 가지고있다. 그러나 나는 내일 나의 지위를 최신의 것으로 바꾸려고 노력할 것이다. – WhS4

답변

1

질문에 대한 의견에서 "내 버전의 코드"를 물어 봤습니다.

 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 

당신이, 내가에만 볼 수 있듯이 : 은 내가했던 것은 내가 먼저 그래서

CALL READ_REACTIONS(species) 

콜 서브 루틴으로 코드를 설정하는 것입니다, 여기에 최소한의 수정 코드,의 선언 블록과 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 

이 코드는 여전히 것을 다시 열고 너무 똑똑하지 각 새로운 종의 요청에 대한 파일을 닫는을 추가해야합니다.