8 Stimmen

Wie kann ich eine PRINT- oder WRITE-Anweisung so formatieren, dass sie die aktuelle Zeile auf dem Konsolenbildschirm überschreibt?

Ich möchte den Fortschritt einer Berechnung, die mit einer DO-Schleife durchgeführt wird, auf dem Konsolenbildschirm anzeigen. Ich kann die Fortschrittsvariable wie folgt auf dem Terminal ausgeben:

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

Die Ausgabe des obigen Codes auf dem Konsolenbildschirm lautet:

10.00 20.00 30.00 40.00 50.00 60.00 70.00 80.00 90.00 100.00

Alles in derselben Zeile, nur umhüllt vom Konsolenfenster.

En ADVANCE='Nein' und das Argument TL10 (tab links so viele Leerzeichen) funktioniert gut, um Text in derselben Zeile zu überschreiben, z. B. die Ausgabe des folgenden Codes:

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

Ist:

500

Anstelle von:

100 500

Wegen des TL4-Bearbeitungsdeskriptors.

Aus diesen beiden Beispielen kann man schließen, daß die WRITE-Anweisung nicht überschreiben kann, was durch eine andere WRITE-Anweisung oder durch eine vorherige Ausführung derselben WRITE-Anweisung (wie in einer DO-Schleife) geschrieben wurde.

Kann dies irgendwie überwunden werden?

Ich verwende den FTN95-Compiler unter Windows 7 RC1 (das Setup-Programm des G95-Compilers zeigt einen Bluescreen für Windows 7 RC1, obwohl es unter Vista gut funktioniert).

Ich kenne die Frage Unterdrückung von Zeilenumbrüchen in Fortran 95-Schreibanweisungen aber bei mir funktioniert es nicht, weil die Antwort auf diese Frage bedeutet, dass eine neue Ausgabe zur vorherigen Ausgabe in derselben Zeile hinzugefügt wird, anstatt dass die neue Ausgabe die vorherige überschreibt.

Vielen Dank im Voraus.

16voto

tony rollett Punkte 141

Die folgenden Angaben sollten systemübergreifend übertragbar sein durch die Verwendung von ACHAR(13) um den Wagenrücklauf zu kodieren.

          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)

3voto

F'x Punkte 11875

Im Rahmen der Fortran-Standards gibt es keine Lösung für diese Frage. Wenn Ihr Compiler jedoch Backslash in Fortran-Strings versteht (GNU Fortran tut dies, wenn Sie die Option -fbackslash ), können Sie schreiben

  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

Dabei wird das Backslash-Zeichen ( \b ), um bereits geschriebene Zeichen in dieser Zeile zu löschen.

NB: Wenn Ihr Compiler nicht versteht advance="no" können Sie auch nicht-standardisierte Tricks anwenden, wie zum Beispiel die Verwendung der $ in der Formatzeichenkette.

1voto

John Boyden Punkte 11

Das Folgende funktioniert perfekt mit g95 Fortran:

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

gab: 5 PDFs

und lässt den Cursor an der Position 1 in derselben Zeile stehen. Bei der nächsten Aktualisierung, wurde die 5 zu einer 10. ASCII 13 (dezimal) ist ein Wagenrücklauf.

-3voto

AMK Punkte 11
OPEN(6,CARRIAGECONTROL ='FORTRAN')
DO I=1,5
WRITE(6,'(1H+" ",I)') I
ENDDO

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X