第一版
class ProgressBar
{
public:
void updateProgress(float value, std::ostream& os = std::cout)
{
set_progress(value);
fillProgress(os);
}
private:
void set_progress(float value)
{
std::lock_guard<std::mutex> lg(mutex_);
progress_ = value;
}
void fillProgress(std::ostream& os)
{
std::lock_guard<std::mutex> lg(mutex_);
if (progress_ > 1.0f)
return;
os << "\r" << std::flush;
os << "[";
const auto completed = static_cast<size_t>(progress_ * bar_width_);
for (size_t i = 0; i < bar_width_; ++i)
{
if (i <= completed)
os << fill_;
else
os << remainder_;
}
os << "]";
os << " " << static_cast<size_t>(progress_ * 100.0) << "%";
fflush(stdout);
}
private:
std::mutex mutex_;
size_t bar_width_ = 50;
std::string remainder_ = "-";
std::string fill_ = "▉";
float progress_ = 0.0f;
};
第一版光标会闪烁,因此改进,完成第二版
第二版
class ProgressBar
{
public:
void updateProgress(float value)
{
set_progress(value);
fillProgress();
}
private:
void set_progress(float value)
{
std::lock_guard<std::mutex> lg(mutex_);
progress_ = value;
}
void fillProgress()
{
std::lock_guard<std::mutex> lg(mutex_);
if (progress_ > 1.0f)
return;
std::string buffer = "";
buffer += "[";
const auto completed = static_cast<size_t>(progress_ * bar_width_);
for (size_t i = 0; i < bar_width_; ++i)
{
if (i <= completed)
buffer += fill_;
else
buffer += remainder_;
}
buffer += "]";
buffer += " " + to_string(static_cast<size_t>(progress_ * 100.0)) + "%";
printf("\r%s", buffer.c_str());
// 解决光标闪烁
// 刷新缓冲区,将缓冲区内的数据输出到设备
fflush(stdout);
}
private:
std::mutex mutex_;
size_t bar_width_ = 50;
std::string remainder_ = "-";
std::string fill_ = "▉";
float progress_ = 0.0f;
};