Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28865 Discussions

Non-advancing output to the screen - * versus output_unit

Arjen_Markus
Honored Contributor I
761 Views

I ran into a little riddle: I wanted to show the progress of my program via a number written to the screen, not on separate lines, but one after the other. This did not work as I expected ,not even after adding a flush statement. It turns out that if you write to the screen using output_unit instead of *, the progress is shown as intended. This is not needed if the writes are followed by a read statement.

Here is a program that shows the behaviour (I tried with Intel Fortran 2015 and 2017, both do the same thing):

program chk
    use iso_fortran_env, only: output_unit

    implicit none

    integer :: i

    do i = 1,10
        !write(*,'(i10)', advance = 'no' ) i
        write( output_unit,'(i10)', advance = 'no' ) i
        flush( output_unit )
        call sleep( 1 )
    enddo

    write(*,'(a)', advance = 'no' ) 'Almost done ...'
    read(*,*) i
end program chk           

Use the first write statement instead of the second to see the effect. Is this behaviour intentional or some odd side effect? (FYI: this does not happen with gfortran). Mind you: this is not really a problem for me, just a riddle.

0 Kudos
6 Replies
Johannes_Rieke
New Contributor III
761 Views

Hi Arjen, I stumbled over this riddle some years ago. Steve confirmed this behavior for ifort. gfortran behaves different. Here is the old thread:

https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/277417

I implemented the carriagecontrol ='fortran'/'+' method in my code and it runs fine for me. But it is not according to standard. I use it therefor in a combination with a preprocessor definition, which checks whether ifort is used (#if defined(__INTEL_COMPILER)).

Best regards, Johannes

0 Kudos
Arjen_Markus
Honored Contributor I
761 Views

Thanks for that thread. I realised that overwriting the output with new stuff was not possible, but for my purpose a slow filling of the screen was acceptable (just so that the first few lines of the output could be read ;)). The difference in behaviour was surprising.

0 Kudos
WHARR5
New Contributor I
761 Views

Hello Arjen,

Here is a subroutine I CALL at the beginning and at the end of my programs for date and time info. Also, I use a modification of it within programs to keep track of execution times. As you can see, my subroutine, 'TIMESTRIPS', relies on Fortran's two intrinsic subroutines: 'DATE_AND_TIME' and 'TIME'.I hope 'TIMESTRIPS' (or your modification of it) proves useful to you.

    PROGRAM TimeExample
    CALL TIMESTRIPS
    end PROGRAM TimeExample
        
    !********************************************************
    !  PROGRAM: SUBROUTINE TIMESTRIPS                       *
    !                                                       *
    !  PURPOSE: To output current date and time information.*
    !********************************************************
    SUBROUTINE TIMESTRIPS

    implicit none

    ! Variables:

    INTEGER::I,J,MYHR,MYMINS
    CHARACTER(8)::HOUR,TODAYIS,DATETIME

    ! Body of TIMESTRIPS:
   
    CALL DATE_AND_TIME(TODAYIS)
   
    WRITE(*,'(25X,12A)')"Today's date is:  ",(TODAYIS(I:I),I=5,6),'/',(TODAYIS(I:I),I=7,8),'/',(TODAYIS(I:I),I=1,4),','
    
    CALL TIME(HOUR)
    DATETIME=HOUR !'DATETIME' is used here as an internal file
    READ(DATETIME,'(I2)')MYHR
    READ(DATETIME,'(3X,I2)')MYMINS
    
    PRINT*  
    IF(MYHR==0)WRITE(*,'(22X2(A,I2)A/)')'and time right now is:     ',MYHR+12,':',MYMINS,' AM'
    IF(MYHR>0.AND.MYHR<12)WRITE(*,'(22X2(A,I2)A/)')'and time right now is:     ',MYHR,':',MYMINS,' AM'
    IF(MYHR==12)WRITE(*,'(22X2(A,I2)A/)')'and time right now is:     ',MYHR,':',MYMINS,' PM'
    IF(MYHR>12)WRITE(*,'(22X2(A,I2)A/)')'and time right now is:     ',MYHR-12,':',MYMINS,' PM'
    
    end SUBROUTINE TIMESTRIPS

 

0 Kudos
Arjen_Markus
Honored Contributor I
761 Views

Thank you for this one, but it actually solves a different problem :). My problem was to show the user that the program is advancing and at some speed. Your routine shows how much time it took.While in itself useful, giving some feedback to the user is psychologically useful.

0 Kudos
gib
New Contributor II
761 Views

Why not use '$' ?

write(*,'(i10,$)') i

To show program progress I often use: write(*,'(a,$)') '.'

0 Kudos
WHARR5
New Contributor I
761 Views

Hello again Arjen,

This may be more like what you were looking for:

 PROGRAM TimeExample
     
    implicit none
    
    !Variables:
    
    INTEGER::I,J
    CHARACTER::CRETURN
    REAL::T,TIMELY
    
    !Body of TimeExample Program:
    
    CRETURN=ACHAR(13) !'Carriage Return' character
    T=SECNDS(0.0) !Initialize Time
    
    PRINT*;PRINT*;WRITE(*,'(31X,A)')'CLOCK'
    DO I=1,10000
        
        TIMELY=SECNDS(T)
        DO J=1,100
            WRITE(*,'(A)',ADVANCE='NO')CRETURN
            WRITE(*,'(25X,F6.1,A)',ADVANCE='NO')TIMELY,' seconds'
        ENDDO !End of J Loop
        
    ENDDO !End of I Loop
    PRINT*;PRINT*

    end PROGRAM TimeExample

Regards, Bill

0 Kudos
Reply