Проблема «Ошибка времени выполнения Fortran: конец файла» при создании связанного списка с указателем (ЧТЕНИЕ в цикле выполнения)

#fortran #gfortran

#fortran #gfortran

Вопрос:

Я создаю связанный список из входного файла. Каждый узел в связанном списке содержит информацию в каждом блоке ввода. Когда я пытаюсь получить значение из входного файла, я назначил несколько строк (по 4 строки каждый раз) в одномерный массив «tmp». Я думаю, что цикл выполнения, который я использовал в цикле «ввод: ВЫПОЛНЕНИЕ», неверен. Но я не знаю, как решить.

Я использую gfortran для компиляции, и при компиляции не возникает ошибок. Я попытался выполнить запись для тестирования в цикле «ввод: ВЫПОЛНЕНИЕ» для тестирования. Результат показывает, что я могу успешно открыть входной файл.

 PROGRAM read
  IMPLICIT NONE

  INTEGER,PARAMETER :: nat=4
  character(len=20) :: filename
  !Derived types to store atom data 
   TYPE :: atom
     CHARACTER(LEN=2) :: atom_name
     REAL, DIMENSION(3) :: coord      
   END TYPE atom
  !The array info stores info of all atom in one time step
  type :: atom_seq
    type(atom),dimension(nat):: info
    type(atom_seq),pointer :: p
  end type atom_seq
  TYPE (atom_seq), POINTER :: head 
  TYPE (atom_seq), POINTER :: tail 
  type(atom), dimension(nat) :: temp

  ! Declare variable
  INTEGER :: istat
  INTEGER :: i=0, n=0

  ! Open input data file
  WRITE(*,*) 'ENTER the file name with the data to be read: '
  READ(*,'(A20)') filename
  NULLIFY(head)
  OPEN( UNIT=9, FILE=TRIM(filename), STATUS="OLD", ACTION="READ", IOSTAT=istat)
  ! Was the open successful
  fileopen: IF (istat == 0) THEN
    input: DO
      !WRITE(*,*) "OPEN done " ! for testing
      READ(9,*)                ! <--when run, error is in this line
      READ(9,*)
      DO i = 1, nat
        READ(9,*,IOSTAT=istat) temp(i)%atom_name, temp(i)%coord(1), temp(i)%coord(2), temp(i)%coord(3)
      ENDDO

      IF (istat /= 0) EXIT
      n = n   1  ! Bump count
      IF (.NOT. ASSOCIATED(head) ) THEN  ! No values in list
        ALLOCATE(head, STAT=istat)       ! Allocate new value
        tail => head                     ! Tail points to new value  
        NULLIFY(tail%p)                  ! Nullify p in new value
        DO i = 1, nat  ! Store number
          tail%info(i)%atom_name = temp(i)%atom_name
          tail%info(i)%coord(1) = temp(i)%coord(1) 
          tail%info(i)%coord(2) = temp(i)%coord(2)
          tail%info(i)%coord(3) = temp(i)%coord(3)
        ENDDO

      ELSE     ! Values already in list
        ALLOCATE(tail%p, STAT=istat) ! Allocate new value
        tail => tail%p
        NULLIFY(tail%p)
        DO i = 1, nat  ! Store number
          tail%info(i)%atom_name = temp(i)%atom_name
          tail%info(i)%coord(1) = temp(i)%coord(1) 
          tail%info(i)%coord(2) = temp(i)%coord(2)
          tail%info(i)%coord(3) = temp(i)%coord(3)
        ENDDO
      END IF
    END DO input
  ELSE fileopen
    WRITE(*,1030) istat
    1030 FORMAT ('File open failed --status =  ', I6)
  END IF fileopen
END PROGRAM read
  

Входной файл: inp

      4
 Particles:1_0
  O         0.8050005000        0.7000000000        3.2350000000
  H         1.4750005000        1.2800000000        2.8650000000
  H         0.8550005000       -0.0900000000        2.7150000000
  O         0.4050005000        0.7500000000       -4.1350000000
     4
 Particles:1_5
  O         0.8799478358        0.6383317306        3.1569568025
  H         1.4046592860        1.2232485826        2.4978364665
  H         1.1472783731       -0.2687458123        3.0229092093
  O         0.5392992531        0.6047144782       -4.0811918365
     4
 Particles:1_10
  O        -3.8021765454        3.1600783692       -4.5455655916
  H        -4.5320715486        3.0937504111        4.9514896261
  H        -3.5088238380        4.0613340230       -4.5394597924
  O        -3.3469012765       -0.7064128847        1.2465212113
  

и ошибка

 hg@xi /home/hg/pole $ ./read 
 ENTER the file name with the data to be read: 
inp
At line XXX of file read.f95 (unit = 9, file = 'inp')
Fortran runtime error: End of file

Error termination. Backtrace:
#0  0x7f1c1fdbb31a
#1  0x7f1c1fdbbec5
#2  0x7f1c1fdbc68d
#3  0x7f1c1ff32a33
#4  0x7f1c1ff364b7
#5  0x7f1c1ff365b8
#6  0x5566d3dc9daf
#7  0x5566d3dca9ed
#8  0x7f1c1f9d0b96
#9  0x5566d3dc9a79
#10  0xffffffffffffffff
  

Я надеюсь устранить проблему. Если моя идея неверна, пожалуйста, дайте несколько предложений по разработке лучшей структуры данных для сохранения данных во входных данных (входной файл может содержать тысячи блоков вместо 3. Он большой, и количество блоков неизвестно до запуска кода. )

Комментарии:

1. Я думаю, что вам также необходимо проверить состояние первого чтения во время цикла. (чтение (9,*)) В противном случае на 4-м цикле произойдет сбой.

2. Я снова протестировал, проблема может заключаться в следующем: он не может завершиться, когда достигнет конца файла, хотя я использовал IF (istat /= 0) EXIT в конце цикла выполнения. Я вставляю a WRITE()"XX" в цикл. результат $ ./read ENTER the file name with the data to be read: inp OPEN done (XX 4 lines) OPEN done (XX 4 lines) OPEN done (XX 4 lines) OPEN done (XX 4 lines) OPEN done At line 35 of file read.f95 (unit = 9, file = 'inp') Fortran runtime error: End of file

3. Я попытался добавить use iso_fortran_env код и изменил IF (istat /= 0) EXIT на if (stat == iostat_end) exit , но проблема все та же.

Ответ №1:

Существует тест на IOSTAT отсутствие с первым выполненным READ в цикле. Когда результат не в порядке, цикл может быть завершен, например, изменить:

 fileopen: IF (istat == 0) THEN
    input: DO
      !WRITE(*,*) "OPEN done " ! for testing
      READ(9,*)                ! <--when run, error is in this line
      READ(9,*)
  

в

 fileopen: IF (istat == 0) THEN
    input: DO
      !WRITE(*,*) "OPEN done " ! for testing
      READ(9,*,IOSTAT=istat)
      IF (istat /=0) EXIT
      READ(9,*)
  

Комментарии:

1. Я тестирую IOSTAT с первым READ , тогда он работает!