- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, everyone. I want to produce a simple progress bar in a text console by using Fortran 90. The bar would be like this.
[bash] 10% |* |[/bash]I want to useadvance="no"in a write statement to generate the bar. Below is therelevantcode.
[fortran]program test implicit none integer(kind=4)::i do i=1, 10 ! Just spend some cpu time to calculate pi. ! This could be replaced by non-standard subroutine sleep(n). call pi call progress(i) ! generate the progress bar. enddo stop end subroutine progress(j) implicit none integer(kind=4)::j,k character(len=17)::bar="???% | |" write(unit=bar(1:3),fmt="(i3)") 10*j do k=1, j bar(6+k:6+k)="*" enddo ! print the progress bar. write(unit=6,fmt="(a1,a17)",advance="no") char(13), bar if (j/=10) then flush(unit=6) else write(unit=6,fmt=*) endif return end subroutine progress[/fortran]I found the binary produced by ifort could only print the final bar, which is
[bash]100%|**********|[/bash]The intermediates are somehow omitted. Some other compilers could produce the desired results.
Is this a bug of my code or ifort?
Thanks in advance!
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It is not a bug in ifort. The Fortran standard does not guarantee that the output with advance='no' is immediately available - this is used to "build" a record. Some implementations do this, some do not.
The following works in Intel Fortran, but may not be portable. Note that the unit has to be opened for FORTRAN carriage control.
The following works in Intel Fortran, but may not be portable. Note that the unit has to be opened for FORTRAN carriage control.
[fortran]program test use ifport implicit none integer(kind=4)::i open (unit=6, carriagecontrol='fortran') do i=1, 10 ! Just spend some cpu time to calculate pi. ! This could be replaced by non-standard subroutine sleep(n). call sleepqq(300) call progress(i) ! generate the progress bar. enddo stop end subroutine progress(j) implicit none integer(kind=4)::j,k character(len=17)::bar="???% | |" write(unit=bar(1:3),fmt="(i3)") 10*j do k=1, j bar(6+k:6+k)="*" enddo ! print the progress bar. write(unit=6,fmt="(a1,a1,a17)") '+',char(13), bar return end subroutine progress[/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you, Steve!
I'm notmajoredin computer science. Prior to reading your post, I have no idea about byte-oriented and record-oriented file systems. I think the I/O facilities provided by record-oriented file systems, e.g. in VMS, are really more powerful than those provided in *nix.
BTW, I find that the desired results could also be produced by using -vms option without defining carriagecontrol in open statement. The only drawback is the first byte of each record is always wasted. Moreover, a compiler supports the VMS I/O system is also required. :(
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I personally think a non-standard, but least-demanded trick is to write it in this way.
[fortran]write(unit=6,fmt="(a1,a20,$)") char(13), bar[/fortran]
The only compiler I've tried that does NOT support the Dollar is f90 from SUN. However, f95 does support it.
May we say that previously SUN was not compatible with "Dollar", but later this might be changed? :D
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The -vms option implicitly sets carriagecontrol='fortran'. What you're looking for is not really tied to the file system, but rather the semantics of Fortran record I/O.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page