- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I want my console application to display a varying number at the same location in the current output line, i.e. overprint it. Example:
DO I = 1, n
! do something
WRITE (*, '(A, I3)') 'Loop count = ', n
END DO
IOW I don't want each loop count report to create a new line (thus scrolling out of the window when n is large)--I want it to keep updating the same line. I know how to do this using Quickwin or API routines, but I desire standard Fortran.
Once upon a time I could accomplish this using carriage control: the output string would be '+Loop count = ', n. But this awkwardly requires the compiler switch '/ccdefault:fortran'. Worse, I understand that carriage control has been eliminated from standard Fortran.
So, how can I do this now?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you just try:
WRITE (*, '(\,A, I3)') 'Loop count = ', n
Or check documentation ->FORMAT
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try this:
program overwrite implicit none integer :: i,j character :: bsp = char(8) ! write(*,10,advance='no')10000 do i=10001,99999 write(*,20,advance='no')(bsp,j=1,5),i end do 10 format('Counter: ',I5) 20 format(5A1,I5) end program
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You could also open the unit with CARRIAGECONTROL='FORTRAN', but you're right that Fortran carriage control is not part of the current standard. mecej4's approach will generally work, though. If you don't require keeping the text at the beginning you could output a single CR (char(13)).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for these suggestions.
reidar: This doesn't do what I want. the backslash simply causes the output to continue on the same line without a CR/LF; the line simply grows longer and longer.
mecej4: This "sort of" works, and the backspace character is a good idea. However, with your code as written the output does not appear until the program completes. If I replace "advance='no'" with "\" or "$" (the older styles of doing the same thing) then it works OK, i.e. the output line is actually displayed each time through the loop. I do not understand this, I always thought that backslash editing, dollar editing, and advance=no were equivalent. I have tried several variations on these formats and conclude they are not. (Perhaps there is some obscure issue lingering in my test program?)
Here's my code snipped that works:
WRITE (*, '(A, $)') ' Loop count = '
bsp = CHAR (8)
DO i = 1, n
WRITE (*, '(3A1, I3, $)') (bsp, j=1,3), i
END DO
! Note that constants '3' must agree in number and be sufficiently large to accommodate the size of i
So, I am still faced with resorting to non-standard IVF extensions to solve this problem.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Which compiler version are you using? I ran mecej4's code and it definitely updated while the program was running. Several versions ago it might not have.
An alternative would be to use nonadvancing output to create a sort of "progress bar".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have two computers. One uses 2013 sp1.3.202. One uses 2011.11.344.
The setting ADVANCE='NO' doesn't work correctly on either one--the output doesn't appear until a subsequent write to the window occurs. A correct result appears on the final screen, but it is no good for real-time tracking.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try by inserting a FLUSH statement after the WRITE statement.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A good suggestion, but it doesn't help.
Moreover, it's a little awkward. This being a console application, I have all the WRITE's going to unit *. FLUSH () requires a unit argument, it doesn't accept FLUSH (*). I tried opening a window to unit 1 and directing all of the writing to that. The program runs the same and appears the same as the original version using unit (*). Then, adding FLUSH (1) was observed to have no effect.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Are you using something other than the default buffering on output to the console? Is the counter display being done on the standard command line console or in a Windows program?
The program in #3 works even with CVF6.6 and Gfortran 4.9.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I checked some old stuff, what used to work with CVF was a "+" sign in column 1, so you should try:
WRITE (*, '('+',A, I3)') 'Loop count = ', n
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think that requires cooperation from the console/DOS-box: it is an ancient type of carriage control, dating from the time of printers with endless papersheets.It may or may not still work - you simply have no way of ensuring it just from the Fortran program.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, that simply requires opening the file with CARRIAGECONTROL='FORTRAN'. Even in CVF that was not the default.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The solution based on carriage control has already been covered in this thread, starting with the very first message. It remains the most convenient way to do it. The complaint is that it was removed from the standard (in 2003) and hence only works through sympathisers of compilers (like Intel) who continue to offer it through extensions. In Intel's case, that would be using a non-standard compiler switch or a non-standard file open option, both as described above.
In the past, when the standards people removed a feature, a work-around or modern replacement was described. Not so in this case. It is awkward to do using strictly standard features. The feature appears to have been removed because of the demise of line printers. I think this was a bad assumption, that "carriage control" was not useful for anything else.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In kernel32.f90 you will find SetConsoleCursorPosition and GetConsoleScreenBufferInfo.
You might want to write generic wrappers, perhaps GOTOXY and WHEREXY that use these functions on Windows, and uses similar functions on Linux or other operating system.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you have a console driver that supports ANSI cursor positioning sequences, such as the one that comes with Cygwin+Gfortran on Windows, or one of the many console programs such as Konsole on Linus, you can try the following:
program overwrite implicit none integer :: i,j character :: esc = char(27) ! write(*,10,advance='no') esc,10000 do i=10001,100000 write(*,20,advance='no') esc,i end do 10 format(A1,'[13;30HCounter : ',I6) 20 format(A1,'[13;40H',I6) end program
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm unsure of that - isn't this a separate program you have to load?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes it is - it is one method that does not look that bad -- there are no good solutions.
It is listed as the currently preferred solution at a number of major help sites and then you run your program in the window.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My proposal #11 works well if you set project -> Properties ->Compability -> VMS = Yes.
integer i,j,n
character*1 bsp
n=1000
WRITE (*, '(A)') ' Loop count = '
WRITE (*, '(A)') ' '
bsp = CHAR (8)
DO i = 1, n
! WRITE (*, '(3A1, I3, $)') (bsp, j=1,3), i
WRITE (*, "('+',3A1, I4)") (bsp, j=1,3), i
END DO
pause
end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Reidar, thanks for the continued attention but as mentioned several times above I reject your solution because it is not standard Fortran. The whole point of this thread is that I know that using carriage control ('+' in column 1) is a good way to perform the overstrike--and a damn good way at that--I was requesting a way that conforms to the standard. I have been using the "+" method for many, many years. But they have now removed it from the standard without providing a replacement or even discussing a reasonable workaround. Such a discussion is what I was looking for.
The many responses kindly provided by several users address that discussion. I conclude that there is not a good standard way to do it.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page