Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!
26732 Discussions

Writing to standard output with advance = 'no'

Garcia__Javier
Beginner
875 Views

This short program works as intended if I compile with gfortran and the option -fbackslash, i.e., it shows a line that states the step number I'm currently in and it updates it every second.

program test                                                                  
    use iso_fortran_env, only: output_unit                                    
                                                                              
    character(len = 24) :: msg                                                
                                                                              
    n = 10                                                                    
    write(msg, '(A, I3, A, I3)') 'Step', 1, ' out of', n                      
    write(output_unit, '(A)', advance = 'no') trim(msg)                       
    call sleep(1)                                                             
                                                                              
    do i = 2, 10                                                              
        write(output_unit, '(A)', advance = 'no') repeat('\b', len(trim(msg)))
        write(output_unit, '(A, I3, A, I3)', advance = 'no')  'Step', i, ' out of', n               
        call sleep(1)                                                         
    enddo                                                                     
end program test

Instead, if I compile with ifort (with the option -assume bscc), it doesn't show anything until the program finishes. How can I get the same behavior I get when compiling with gfortran?

Thanks!

0 Kudos
4 Replies
Steve_Lionel
Black Belt Retired Employee
875 Views

In order to make the output available, you need to insert a FLUSH statement, gfortran and Intel Fortran behave differently here, both are correct.

So a modified program (that doesn't require a special compile switch) would be:

program test                                                                  
    use iso_fortran_env, only: output_unit  
    use iso_c_binding, only: c_backspace
                                                                              
    character(len = 24) :: msg
                                                                             
    n = 10                                                                    
    write(msg, '(A, I3, A, I3)') 'Step', 1, ' out of', n                      
    write(output_unit, '(A)', advance = 'no') trim(msg) 
    flush(output_unit)
    call sleep(1)                                                             
                                                                              
    do i = 2, 10                                                              
        write(output_unit, '(A)', advance = 'no') repeat(c_backspace, len_trim(msg))
        write(output_unit, '(A, I3, A, I3)', advance = 'no')  'Step', i, ' out of', n      
        flush(output_unit)
        call sleep(1)                                                         
    enddo                                                                     
end program test

This partially works, in that the output appears each iteration. But the backspaces never get written to the output unit, where I think they should. To fix this, add a second flush after the first write, like so:

program test                                                                  
    use iso_fortran_env, only: output_unit  
    use iso_c_binding, only: c_backspace
                                                                              
    character(len = 24) :: msg
                                                                             
    n = 10                                                                    
    write(msg, '(A, I3, A, I3)') 'Step', 1, ' out of', n                      
    write(output_unit, '(A)', advance = 'no') trim(msg) 
    flush(output_unit)
    call sleep(1)                                                             
                                                                              
    do i = 2, 10                                                              
        write(output_unit, '(A)', advance = 'no') repeat(c_backspace, len_trim(msg))
        flush(output_unit)
        write(output_unit, '(A, I3, A, I3)', advance = 'no')  'Step', i, ' out of', n      
        flush(output_unit)
        call sleep(1)                                                         
    enddo                                                                     
end program test

I think it's a bug that the flush after writing the backspaces is needed - I'll report that to Intel. However, this version should also work in gfortran.

Garcia__Javier
Beginner
875 Views

This works perfectly for me, thanks Dr. Fortran!

Steve_Lionel
Black Belt Retired Employee
875 Views

Issue 04436367 has been submitted on this. It is reproducible with this small program:

program test
implicit none

write (6,'(A)', advance='NO') 'ABCDE'
!flush(6)
write (6,'(A)', advance='NO') 'FGHIJ'
flush(6)
end

 

Steve_Lionel
Black Belt Retired Employee
875 Views

Bug confirmed by Intel support, sent on to development for a fix.

Reply