Frage

Mein Programm (das zufällig in Perl ist, obwohl ich glaube, dass diese Frage nicht Perl-spezifisch ist) gibt Statusmeldungen an einer Stelle im Programm des Formulars aus Progress: x/yy Wo x Und yy sind eine Zahl, wie: Progress: 4/38.

Ich möchte die vorherige Ausgabe „überschreiben“, wenn eine neue Statusmeldung gedruckt wird, damit ich den Bildschirm nicht mit Statusmeldungen fülle.Bisher habe ich Folgendes versucht:

my $progressString = "Progress\t$counter / " . $total . "\n";
print $progressString;
#do lots of processing, update $counter
my $i = 0;
while ($i < length($progressString)) {
    print "\b";
    ++$i;
}

Das Rückschrittzeichen wird nicht gedruckt, wenn ich eine neue Zeile einfüge $progressString.Wenn ich jedoch die neue Zeile weglasse, wird der Ausgabepuffer nie geleert und es wird nichts gedruckt.

Was ist hierfür eine gute Lösung?

War es hilfreich?

Lösung

Verwenden Sie Autoflush mit STDOUT:

local $| = 1; # Or use IO::Handle; STDOUT->autoflush;

print 'Progress: ';
my $progressString;
while ...
{
  # remove prev progress
  print "\b" x length($progressString) if defined $progressString;
  # do lots of processing, update $counter
  $progressString = "$counter / $total"; # No more newline
  print $progressString; # Will print, because auto-flush is on
  # end of processing
}
print "\n"; # Don't forget the trailing newline

Andere Tipps

Sagen

$| = 1

Irgendwo zu Beginn Ihres Programms können Sie die automatische Leerung für den Ausgabepuffer aktivieren.

Erwägen Sie auch die Verwendung von „ “, um den Cursor zurück an den Anfang der Zeile zu bewegen, anstatt explizit zu zählen, wie viele Leerzeichen Sie zum Zurückbewegen benötigen.

Wie Sie sagten, drucken Sie keine neue Zeile aus, während Ihr Fortschrittszähler läuft, sonst drucken Sie Ihren Fortschritt in einer separaten Zeile aus, anstatt die alte Zeile zu überschreiben.

Ich weiß, es ist nicht ganz das, wonach Sie gefragt haben, aber möglicherweise besser.Ich hatte das gleiche Problem, und anstatt mich damit zu befassen, habe ich mich intensiver mit der Verwendung beschäftigt Term::ProgressBar was auch schön aussieht.

Sie können auch die verwenden ANSI-Escape-Codes um den Cursor direkt zu steuern.Oder Sie können verwenden Begriff::ReadKey dasselbe zu tun.

Ich musste heute etwas Ähnliches in Angriff nehmen.Wenn es Ihnen nichts ausmacht, die gesamte Zeile erneut zu drucken, können Sie Folgendes tun:

print "\n";
while (...) {
     print "\rProgress: $counter / $total";
     # do processing work here
     $counter++;
}
print "\n";

Das Zeichen „ “ ist ein Wagenrücklaufzeichen – es bringt den Cursor zurück an den Zeilenanfang.Auf diese Weise überschreibt alles, was Sie ausdrucken, den Text der vorherigen Fortschrittsbenachrichtigung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top