立即在控制台屏幕上的同一行打印

时间:2017-07-24 05:21:40

标签: windows fortran intel-fortran

我试图在控制台屏幕上打印一些长迭代进度指示器。具体来说,我希望在控制台屏幕上显示这样的内容:

----|----|----|----|

这是,在每次迭代后打印-(不是5的倍数),并在每5次迭代后打印|。这应该是实时发生的:每次迭代一个字符。

我尝试将WRITE语句与ADVANCE='NO'选项一起使用,但所需的输出仅在执行完所有程序后显示在屏幕上,或者在我使用另一个WRITE语句后显示使用ADVANCE='YES'选项。

这是我的代码:

PROGRAM TEST

  IMPLICIT NONE
  INTEGER :: i

  DO i = 1,20
     CALL SLEEP(2)
     IF (MOD(i,5).EQ.0) THEN
        WRITE(*,'(A)',ADVANCE='NO'), '|'
     ELSE
        WRITE(*,'(A)',ADVANCE='NO'), '-'
     END IF
  END DO

END PROGRAM TEST

我使用SLEEP子例程来模拟每次迭代需要花费大量时间的事实。

3 个答案:

答案 0 :(得分:2)

flush语句可用于表示已写入文件的数据“可用”。该陈述的含义仍然依赖于处理器,但通常你会得到你想要的问题。

flush语句需要一个单元号。要输出到控制台,您可以使用ISO_FORTRAN_ENV中的OUTPUT_UNIT。然后,英特尔Fortran 17.0及更早版本应显示您想要的行为,对于当前的ifort beta,您还需要在write语句中使用OUTPUT_UNIT(这可能是编译器/编译器运行时错误)。

(您还应修复WRITE语句中的语法错误。)

答案 1 :(得分:1)

确实,您的设置理论上应该可行(考虑到不同编译器的不同行为等)。上面使用FLUSH(索引)语句的建议,使用与标准输出相关的索引,甚至可以解决不同编译器之间的差异。但是,在某些环境(更具体地说是群集和HPC超级计算机)中,这仍然无法解决您的问题。虽然implementing a progress-bar myself我遇到了同样的问题,但我得出以下结论:

  

HPC系统可能在输出之前执行大量数据缓冲,以提高机器的效率(磁盘写入是最慢的内存访问选项)......因此,这有时会否决我们的flush命令。反过来,进度条在实际完成之前不会显示太多进展,此时整个条形图将立即显示。有一些选项可以强制基础设施不使用此缓冲(并且系统管理员通常不会理解这一点),例如通过设置编译器标志 -assume nobuffered_stdout 。因此,HPC应用程序的最佳解决方案是构建略微修改的进度条,其中不使用回车。

您可以通过在桌面上运行相同的代码轻松测试,FLUSH语句将为您提供预期的行为。

答案 2 :(得分:0)

根据IanH和DannyVanpoucke关于flush语句的建议,这是一个按预期工作的代码版本:

PROGRAM TEST

  IMPLICIT NONE
  INTEGER :: i

  DO i = 1,20
     CALL SLEEP(2)
     IF (MOD(i,5).EQ.0) THEN
        WRITE(UNIT=6,FMT='(A)',ADVANCE='NO'), '|'
        FLUSH(UNIT=6)
     ELSE
        WRITE(UNIT=6,FMT='(A)',ADVANCE='NO'), '-'
        FLUSH(UNIT=6)
     END IF
  END DO

END PROGRAM TEST

正如问题下面的一些评论所指出的,似乎需要使用flush语句使缓冲区中的信息可用是英特尔Fortran特定的问题。