- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a console application that does nothing but math operations.
To inform the user about the progress, it prints messages to the screen like:
Step 1 completed…
Step 2 completed… etc
aso…
Instead I want the program to reprint or scroll on a single line by omitting the line feed.
In former days this could be easily arranged with the statements:
WRITE(IDO,911)N
911 FORMAT('+'T5,'Step',I3,' Completed…')
But with IVF this does not work….
Do anybody have a clue how a “scroll” function could be arranged?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can try to use the carriagecontrol ='fortran'
and the + character. You can find an example in an older post:
https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/277417
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is not so much a problem of Intel Fortran as a change in the behaviour of consoles in general in comparison with the old days.
A simple way to solve this - no guarantee though - is to use code like the small program below:
! noscroll.f90 -- ! Can we prevent scrolling? ! program noscroll implicit none integer :: i do i = 1,10 write(*,'(i4,a1)', advance = 'no') i, achar(13) enddo endprogram noscroll
The "advance='no'" option makes sure no carriage return line feed is emitted, causing the console to start a new line and the achar(13) character is used to make the console "cursor" go back. The net effect: you write to the start of the same line with each iteration.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can try to use the carriagecontrol ='fortran'
and the + character. You can find an example in an older post:
https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/277417
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can also call a C Runtime Library routine to emit a character or null terminated string.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you all for help.
The "advance=no" option seems to suppress both the LF and the position T5, thus produces an endless line........
So far I found the simplest solution was to open a user window with option "carriagecontrol='fortran' ".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hm, odd, I adjusted the write statement in the program I posted to:
write(*,'(t5,a1,i4,a1)', advance = 'no') '!', i, achar(13)
and got:
! 10
on the screen. Si in my case the T5 edit is working fine. "advance='no'" does suppress the carriage return AND the line feed. Which is why the write statement explicitly include writing the carriage return.
Using the carriagereturn option is definitely the easiest fix, but note that it is an Intel Fortran extension, whereas the above is standard Fortran ;).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok, in my test I overlooked achar(13) in the output list, sorry. I tested once more, also by directly implementing the "write" statement from your example. However, it did not produce any output but from the "PRINT" statement. A list of my program is shown below. There must be something else which is different..
! The program is invoked from a dialogue in a Win32 program or from a command prompt
program TVSimulation USE TVA_CalcControl implicit none ! Variables INTEGER IDUM,ISTAT,i IUNI=401 ! defined in TVA_CalcControl ! open(file='user', unit=IUNI,carriagecontrol='FORTRAN') ! This works ! open(file='user', unit=IUNI) ! ... neither ! print *, '************ START TVSIM ************' do i = 1,10 ! write(IUNI,'(T5,i4,a1)', advance = 'no') i, achar(13) write(*,'(t5,a1,i4,a1)', advance = 'no') '!', i, achar(13) enddo pause call TVSim(1,ISTAT) print *, 'PRESS RETURN TO EXCIT AND CLOSE WINDOW' READ(*,*) end program TVSimulation
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It may depend on ifort version, but try Arjen's method with a FLUSH statement on the console unit.
program noscroll_with_flush use, intrinsic :: iso_fortran_env, only: output_unit use ifport, only: sleepqq implicit none integer :: i do i = 1,99 write(*,'(i2,a1)', advance = 'no') i, achar(13) flush(output_unit) ! <----------- ! Slow down so we can see output. call sleepqq(100) end do end program noscroll_with_flush
Recent Windows 10 includes a much enhanced console subsystem, that can basically emulate a terminal (if you are running Windows Subsytem for Linux, it is a terminal). You can have all sorts of fun with it.
program noscroll_deluxe use ifwin, only: & handle, & std_output_handle, & invalid_handle_value, & getstdhandle, & bool, & dword, & setconsolemode use ifport, only: sleepqq implicit none integer(handle) :: stdout_handle integer(bool) :: rc integer(dword) :: mode character(2) :: col integer :: i ! Not defined in 17.0.1's kernel32 module. integer(dword), parameter :: & enable_virtual_terminal_processing = int(z'0004',dword) interface ! The description of this in ifort's kernel32.f90 is a bit wonky. function GetConsoleMode(hConsoleHandle, lpMode) & bind(c, name='GetConsoleMode') use ifwinty integer(handle), value :: hConsoleHandle integer(dword), intent(out) :: lpMode !DEC$ ATTRIBUTES STDCALL :: GetConsoleMode integer(bool) :: GetConsoleMode end function GetConsoleMode end interface stdout_handle = getstdhandle(std_output_handle) if (stdout_handle == invalid_handle_value) & error stop 'no stdout!' rc = getconsolemode(stdout_handle, mode) if (rc == 0) & error stop 'stdout not a console!' mode = ior(mode, enable_virtual_terminal_processing) rc = setconsolemode(stdout_handle, mode) if (rc == 0) & error stop 'windows version too old :(' print "()" do i = 1,99 write (col, '(i2)') mod(i,8) + 30 print "(a,i2)", char(27) // '[1F' // char(27) // '[' // col // 'm', i ! Slow down so we can see output. call sleepqq(100) end do print "(a)", char(27) // '[0m' end program noscroll_deluxe
See https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032(v=vs.85).aspx for information on the support escape codes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I was curious about the PAUSE statement in your sample program, but it still works indeed :). The problem for which Ian proposes a FLUSH statement is simple: at the end of the do-loop the write position is again at the start of the line that holds the last output (" ! 10"). So the message from PAUSE overwrites that.
An alternative could be:
program noscroll implicit none integer :: do i = 1,10 write(*,'(t5,a1,i4,a1)', advance = 'no') '!', i, achar(13) enddo write(*,*) '' ! Force the output cursor to the next line endprogram noscroll
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you all for interesting suggestions!
Well, I checked my latest purchased textbook about Fortran, "Fortran 90 Explained" by M. Metcalf and J. Reid. There is a chapter about Fortran carriage control which states: "The first character on each output record (eg to the lineprinter) must be of default kind. It is not printed but interpreted as a carriage control character...The carriage control characters defined by the standard are: b - to start a new line, + - to remain on the same line (overprint), 0 - to skip a line, 1 - to advance to the beginning of next page." But of course the standard may have been changed..
With IVF you have to open a device with the carriagecontol="fortran" which is IVF specific extension to make the overprint work..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, there is slightly more to it than that: the console has to cooperate. Just think of all those programming languages that do not use this Fortran (or perhaps FORTRAN) feature. C for instance requires you to explicitly specify a new line to go the next line in the console and any character will simply be printed. Apparently the CARRIAGECONTROL keyword arranges for the output to obey the conventions used by FORTRAN in the old days.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, there is slightly more to it than that: the console has to cooperate. Just think of all those programming languages that do not use this Fortran (or perhaps FORTRAN) feature. C for instance requires you to explicitly specify a new line to go the next line in the console and any character will simply be printed. Apparently the CARRIAGECONTROL keyword arranges for the output to obey the conventions used by FORTRAN in the old days.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page