Why does using command PRINT in Fortran overwrite

2020-05-08 02:15发布

问题:

I'm writing my code and using input and output feature in Fortran. The code looks like this (only for simplification):

PROGRAM TEST

  REAL, DIMENSION(1000):: A
  REAL:: B
  INTEGER::T

 !Defining input and output  
  OPEN(UNIT=1, FILE='input.dat', STATUS='OLD')
  OPEN(UNIT=2, FILE='output.dat', STATUS='NEW')  

 !Reading from file "input.dat"  
  READ(1,*) (A(I),I=1,1000)

 !Just for initial condition
  B=0.0  

  DO T=1, 10
    PRINT *, 'Step =', T 
        DO I=1, 1000     
           B=B+1.0     
           A(I)=A(I)/B  
        END DO
  END DO

 !Writing results into file "output.dat"
   DO I=1, 1000
      WRITE (2,100) I, A(I)
   END DO 
   100 FORMAT (' ',T3, I12, T17, F14.4)   

END PROGRAM TEST

I was using Gfortran 5.3 and the result was not like what I was expecting. I expected to obtain the result of variable T on the screen (or terminal in Ubuntu OS) when the program is running and the variables I and A(I) are written into file output.dat. I didn't have problem with the variables I and A(I), since they were successfully written into file output.dat. The problem is with variable T, where it didn't appear on the terminal, but it was written into the file input.dat. Well, even the previous file in file input.dat were not overwritten. Could anyone give me the suggestion?

FYI, I have also tried on other compiler (using Windows OS), e.g.:

  1. Microsoft Fortran Powerstation (the very old one): but it worked like I expected.
  2. MinGW-w64 (GCC Version for Windows): but it didn't work properly.

回答1:

This is likely because with your particular combination of platform/compiler/compiler version/compiler options, unit 1 is the preconnected unit for the the console.

Your OPEN statement directs that unit to your input file. Consequently, PRINT statements that implicitly address that unit then direct their output to the same file.

Use a different unit number - choosing values greater than 10 is generally safe from compiler preconnected units. For further safety you can use an INQUIRE(UNIT=unit_number, EXIST=some_logical_variable) statement to check whether a particular unit is connected to a file ahead of your OPEN statement - and choose a different unit number if so. Ideally, if you are writing to Fortran 2008 you can use the NEWUNIT specifier.

(Don't hard-code the values of unit numbers into your input/output statements - they should always be represented by a variable or named constant, such that the value can be easily set/changed in the one place.)



回答2:

I've found the answers. Actually the code I've posted above will run well on Gfortran 5.3, since I used OPEN(UNIT=1,...) and OPEN(UNIT=2,...) which is there will be no problem since I am using 1 and 2. I just wrote this simple case to represent my real code without checking it first. But actually in my real code, I used two statements that OPEN(UNIT=5,...) and OPEN(UNIT=6,...) existed, which are not allowed in Fortran, since:

  1. UNIT=5 declares Standard In which is used to read in data from the keyboard.
  2. UNIT=6 declares Standard Out which is used to print general output to the screen.
  3. UNIT=0 declares Standard Error which is used to print error messages to the screen.

I didn't realize before since I'm working on quite old code, so O need to rewrite it into a newer version one. So, in order to avoid the problems, just don't use UNIT=5, UNIT=6 and UNIT=0.