Domanda

Il mio programma (che accade essere in Perl, anche se non ritengo che questa domanda sia specifica perl) Messaggi di stato delle uscite in un punto nel programma del modulo Progress: x/yy in cui x e yy sono un numero, come: Progress: 4/38.

Mi piacerebbe "sovrascrivere" l'output precedente quando viene stampato un nuovo messaggio di stato in modo da non compilare lo schermo con i messaggi di stato.Finora, ho provato questo:

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;
}
.

Il carattere del backspace non stampa se includo una nuova linea in $progressString.Se lascio fuori la nuova riga, tuttavia, il buffer di uscita non è mai arrossito e niente stampe.

Qual è una buona soluzione per questo?

È stato utile?

Soluzione

Utilizzare Autoflush con 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
.

Altri suggerimenti

Say

$| = 1
.

Da qualche parte all'inizio del tuo programma per attivare automaticamente l'autoflush per il buffer di uscita.

Considera inoltre l'utilizzo di "\ r" per spostare il cursore all'inizio della linea, anziché cercare di contare esplicitamente quanti spazi è necessario tornare indietro.

Come hai detto, non stampare una nuova linea mentre il contatore dei progressi è in esecuzione oppure stampare i tuoi progressi su una linea separata invece di sovrascrivere la vecchia linea.

So che non è proprio quello che hai chiesto, ma forse meglio.Sono accaduto su questo stesso problema e così piuttosto che affrontarlo troppo è andato a usare Term::ProgressBar che sembra anche bello.

Puoi anche utilizzare il Codici di fuga ANSI per controllare direttamente il cursore.Oppure puoi usare termine :: readyey per fare la stessa cosa.

Ho dovuto affrontare qualcosa di simile a questo oggi. Se non ti dispiace la ristampa dell'intera linea, potresti fare qualcosa del genere:

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

Il carattere "\ r" è un ritorno a capofitto ... porta il cursore all'inizio della linea.In questo modo, tutto ciò che stampati sovrascrive il precedente testo di notifica di avanzamento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top