Come ripristinare le linee da cout?

Sto codificando un monitoraggio delle attività, che aggiorna i progressi delle attività utilizzando cout. Mi piacerebbe visualizzare un avanzamento di attività per riga, quindi devo eseguire il rollback di diverse righe della console.

Insisto su “diversi” perché \b fa il lavoro per una riga, ma non cancella \n tra le righe.

Ho provato std::cout.seekp(std::cout.tellp() - str.length()); ma tellp() restituisce -1 (errore).

Puoi fare cout << '\r'; per saltare all'inizio della riga corrente, ma spostarsi verso l'alto è specifico del sistema. Per Unix, vedi man termcap e man terminfo (e cerca cursor_up ). Sui terminali compatibili ANSI (come i terminali più moderni disponibili su Unix), questo funziona per spostarsi verso l'alto: cout << "\e[A"; .

Non provare a cercare in cout , non è consigliabile la maggior parte delle volte (tranne quando viene reindirizzato a un file).

Come menzionato in altre risposte, l'uso della libreria ncurses (o slang ) fornisce una buona astrazione per l'I / O del terminale su Unix.

Usa una libreria di formattazione di output come ncurses se puoi; questo semplifica notevolmente la manipolazione del terminale.

Né C né C ++ definiscono nulla del genere. Hai bisogno di una manipolazione terminale esplicita. Su Unix puoi usare curses . Non ho idea di cosa ci sia per Windows.

So che questo è un vecchio post, ma l’accettato non copre i casi in cui cout è convogliato verso un programma o un file e questa è la parte superiore delle mie ricerche su google. Quanto segue gestirà sia lo stdout con pipe che quello non con un comportamento leggermente diverso.

 #include  #include  #include  #ifdef _WIN32 #include  #else #include  #define _isatty isatty #define _fileno fileno #endif const std::function progress_printer(_isatty(_fileno(stdout)) == 1 ? [](const size_t& i) { std::cout << "\rNumber " << i << std::flush; } : [](const size_t& i) { static std::ios::off_type last(-1); if(last != -1) std::cout.seekp(last, std::ios::beg); last = std::cout.tellp(); std::cout << "Number " << i << std::endl; } ); 

Questo non è testato su Windows, ma dovrebbe funzionare. Quello che fa è rilevare se il descrittore di file o è un tty. Se è così, scrive "\ r" se la posizione non è cambiata dall'ultima volta che è stata stampata o una nuova riga. Se non è una nuova riga, cerca l'ultimo posto in cui si trovava dopo la stampa.

Si comporta in modo diverso per i file rispetto a tty. Per un file, se qualcosa viene esportato nello stream tra le stampe, può sovrascrivere tutto o parte di ciò che è stato scritto anche dopo le nuove righe. Per le ttys sovrascrive i caratteri all'inizio della riga corrente.

Spero che aiuti;) [Dovrebbe funzionare su Linux.]

 // "\e[0K" Clear line from cursor to the end cout << "\e[A\r\e[0K"<