简体   繁体   中英

Fortran Reading characters from file - no output

So I'm trying to understand some basic fortran IO and having trouble. I've written the following

program RFF
implicit none
! Variables
integer :: ierr    
character (:), allocatable :: Filename     
character (:), allocatable :: read_in 

! Body of RFF
Filename = 'string_test.txt' 
open(10, file=Filename, status='old', action='read',iostat=ierr) !What is iostat? 

do while (ierr.eq.0) !What is this do loop doing exactly? 
    read(10,'(A)',iostat = ierr) read_in !What does '(A)' mean? I know it's a format descriptor, but nothing beyond that 
    print*, read_in !Nothing gets output to the terminal here        
enddo

write(*,*) 'Press Enter to Exit'
read(*,*) 

!Is deallocating dynamically allocatable strings something I should do? 
deallocate(Filename) 
end program RFF

Which I've fed the very simple text file containing the word 'arbitrary' and nothing else. When I run the program, nothing crashes but nothing gets output to the terminal, either. Can someone help me understand what is going on? Note I've inserted a number of other questions into the comments of the code I've pasted. I'd like help understanding those as well.

Thanks

The real problem is that you must allocate read_in before you assign to it with read . One other thing: iostat is used to indicate either completion status or a possible error condition. See the code comments and official docs for other details (for example, here ).

Here is a working solution:

program main
    implicit none

    character(len=20) :: read_in                     ! fixed-length string
    character(len=:), allocatable :: word, filename  ! allocatable strings
    integer :: iostat_1, iostat_2                    ! status indicators
    integer :: lun                                   ! file logical unit number

    filename = 'read_test.txt'                       ! allocate on assignment
    iostat_1 = 0                                     ! initialization
    iostat_2 = 0

    open(newunit=lun, file=filename, status='old', iostat=iostat_1)
    if (iostat_1 == 0) then                          ! no error occurred
        do while(iostat_2 == 0)                      ! continues until error/end of file
            read(lun, '(a)', iostat=iostat_2) read_in
            if (iostat_2 == 0) then
                word = trim(read_in)                 ! allocate on assignment to trimmed length.
            endif
        enddo
        if (allocated(word)) then
            print *, "read_in:", read_in
            print *, "len(read_in)", len(read_in)
            print *, "Word:", word
            print *, "len(word)=", len(word)
        else
            print *, "Word was not allocated!"
        endif
    endif
end program main

Example output:

 read_in:arbitrary
 len(read_in)          20
 Word:arbitrary
 len(word)=           9

There are two questions in your one code, so let me address them first:

  • What is iostat ? -- iostat is an error code relating to the I/O statement. If everything worked fine, it will be set to 0 , if not, it will have a non-zero value. Examples on what could go wrong when trying to open a file:

    • File doesn't exist
    • Directory doesn't exist
    • User doesn't have permission to open the file
  • What is (A) ? -- This is the format string. (A) refers to a string of arbitrary length. See here for more information

The code looks as if it should work, however the result isn't what you expect. There are two possibilities that spring to my mind:

  1. The file you are trying to read doesn't exist, or doesn't exist in the directory that you are executing the program in, or you don't have the permission to read it. This results in ierr being set to a non-zero error code (corresponding to 'File not Found'). This results in the do loop not executing even once since the ierr isn't zero to start with.

    I recommend using the newer iomsg statement in addition to iostat . iomsg is a string that corresponds to a human-readable explanation to what went wrong.

     character(len=100) :: iomsg <snip> open(10, file=Filename, status='old', action='read',iostat=ierr, iomsg=iomsg) if (ierr /= 0) then print*, "Error opening file " // trim(Filename) print*, iomsg STOP 1 end if 
  2. The file exist, but is empty. This would result in nothing being printed. Just check to be sure nothing has changed in the file.

Hint, both iostat and iomsg are available in all file I/O operations, so also for read , write , and even close . It can't hurt to use them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM