Я знаю, что это старый пост, но принятый не охватывает случаи, когда cout передается в программу или файл, и это верхняя часть моих поисков в Google.Следующее будет обрабатывать как поточечный, так и непайпированный стандартный вывод с немного другим поведением.
#include <iostream>
#include <functional>
#include <stdio.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#define _isatty isatty
#define _fileno fileno
#endif
const std::function<void(const size_t&)> 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;
}
);
Это не проверено в Windows, но должно работатьЧто он делает, так это определяет, является ли файловый дескриптор или tty.Если это так, то он просто пишет '\ r', если позиция не изменилась с момента последней печати или перевода строки.Если это не символ новой строки, он ищет место, которое было последним после печати.
Он ведет себя иначе для файлов, чем для tty.Для файла, если что-то выводится в поток между отпечатками, он может перезаписать часть или все написанное даже после перевода строки.Для ttys он просто перезаписывает символы в начале текущей строки.