How do I format a PRINT or WRITE statement to overwrite the current line on the console screen?

20,874

Solution 1

There is no solution to this question within the scope of the Fortran standards. However, if your compiler understand backslash in Fortran strings (GNU Fortran does if you use the option -fbackslash), you can write

  write (*,"(A)",advance="no") "foo"
  call sleep(1)
  write (*,"(A)",advance="no") "\b\b\bbar"
  call sleep(1)
  write (*,"(A)",advance="no") "\b\b\bgee"
  call sleep(1)
  write (*,*)
  end

This uses the backslash character (\b) to erase previously written characters on that line.

NB: if your compiler does not understand advance="no", you can use related non-standard tricks, such as using the $ specifier in the format string.

Solution 2

The following should be portable across systems by use of ACHAR(13) to encode the carriage return.

          character*1 creturn
    !   CODE::
          creturn = achar(13)  !  generate carriage return
    !   other code ...
          WRITE( * , 101 , ADVANCE='NO' ) creturn , i , npoint
101     FORMAT( a , 'Point number : ',i7,' out of a total of ',i7)

Solution 3

The following worked perfectly using g95 fortran:

      NF = NF + 1
      IF(MOD(NF,5).EQ.0) WRITE(6,42,ADVANCE='NO') NF, ' PDFs'//CHAR(13)
  42  FORMAT(I6,A)

gave: 5 PDFs

leaving the cursor at the #1 position on the same line. On the next update, the 5 turned into a 10. ASCII 13 (decimal) is a carriage return.

Share:
20,874

Related videos on Youtube

Geoffrey
Author by

Geoffrey

Updated on April 11, 2020

Comments

  • Geoffrey
    Geoffrey over 3 years

    I want to display the progress of a calculation done with a DO-loop, on the console screen. I can print out the progress variable to the terminal like this:

    PROGRAM TextOverWrite_WithLoop
    IMPLICIT NONE
    INTEGER :: Number, Maximum = 10
     DO Number = 1, MAXIMUM   
      WRITE(*, 100, ADVANCE='NO') REAL(Number)/REAL(Maximum)*100     
      100 FORMAT(TL10, F10.2)
      ! Calcultations on Number     
     END DO    
    END PROGRAM TextOverWrite_WithLoop
    

    The output of the above code on the console screen is:

    10.00 20.00 30.00 40.00 50.00 60.00 70.00 80.00 90.00 100.00

    All on the same line, wrapped only by the console window.

    The ADVANCE='No' argument and the TL10 (tab left so many spaces) edit descriptor works well to overwrite text on the same line, e.g. the output of the following code:

    WRITE(*, 100, ADVANCE='NO') 100, 500
    100 FORMAT(I3, 1X, TL4, I3)
    

    Is:

    500

    Instead of:

    100 500

    Because of the TL4 edit descriptor.

    From these two instances one can conclude that the WRITE statement cannot overwrite what has been written by another WRITE statement or by a previous execution of the same WRITE satement (as in a DO-loop).

    Can this be overcome somehow?

    I am using the FTN95 compiler on Windows 7 RC1. (The setup program of the G95 compiler bluescreens Windows 7 RC1, even thought it works fine on Vista.)

    I know about the question Supressing line breaks in Fortran 95 write statements, but it does not work for me, because the answer to that question means new ouput is added to the previous output on the same line; instead of new output overwriting the previous output.

    Thanks in advance.

    • DigitalRoss
      DigitalRoss about 14 years
      Which compiler and OS are you on?
    • Geoffrey
      Geoffrey about 14 years
      @digitalross, compiler = FTN95, OS = Windows 7 RC1
  • Nathan Taylor
    Nathan Taylor almost 14 years
    You should use the [code /] tags (or indenting) to syntax highlight your code and make it more readable. :)
  • Nathan Tuggy
    Nathan Tuggy over 8 years
    Generally, answers are much more helpful if they include an explanation of what the code is intended to do, and why that solves the problem without introducing others. (This post was flagged by at least one user, presumably because they thought an answer without explanation should be deleted. Or maybe the "probably" raised their hackles.)
  • Vladimir F Героям слава
    Vladimir F Героям слава almost 6 years
    This does deserve an explanation. Note CARRIAGECONTROL = is not standard conforming and re-opening unit 6 (let's assume it is the output_unit) can be tricky, particularly with non-standard specifiers. Also, Holleriths are deleted from modern Fortran. You should explain the meaning of the 1H+" ". Also, in standard Fortran you must use I0, just I is not allowed.
  • Javier Garcia
    Javier Garcia almost 4 years
    As Dr. Fortran pointed to me in this thread, if you use c_backspace from module iso_c_binding, then you don't need special compiler options. The write command would be repeat(c_backspace,3) // "gee" instead of "\b\b\bgee".
  • Javier Garcia
    Javier Garcia almost 4 years
    Also, if you are using ifort, you'll need to call flush after each write command.

Related