赞
踩
progressBar.hpp:
- #ifndef __PROGRESSBAR_HPP
- #define __PROGRESSBAR_HPP
-
- #include <iostream>
- #include <stdexcept>
- #include <string>
-
- // the following are UBUNTU/LINUX ONLY terminal color codes.
- #define RESET "\033[0m"
- #define BLACK "\033[30m" /* Black */
- #define RED "\033[31m" /* Red */
- #define GREEN "\033[32m" /* Green */
- #define YELLOW "\033[33m" /* Yellow */
- #define BLUE "\033[34m" /* Blue */
- #define MAGENTA "\033[35m" /* Magenta */
- #define CYAN "\033[36m" /* Cyan */
- #define WHITE "\033[37m" /* White */
- #define BOLDBLACK "\033[1m\033[30m" /* Bold Black */
- #define BOLDRED "\033[1m\033[31m" /* Bold Red */
- #define BOLDGREEN "\033[1m\033[32m" /* Bold Green */
- #define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */
- #define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */
- #define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */
- #define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */
- #define BOLDWHITE "\033[1m\033[37m" /* Bold White */
-
- class progressbar {
- public:
- // default destructor
- ~progressbar() = default;
-
- // delete everything else
- progressbar(progressbar const&) = delete;
- progressbar& operator=(progressbar const&) = delete;
- progressbar(progressbar&&) = delete;
- progressbar& operator=(progressbar&&) = delete;
-
- // default constructor, must call set_niter later
- progressbar();
- progressbar(const std::string& type, int n, bool showbar = true);
-
- // reset bar to use it again
- void reset();
- // set number of loop iterations
- void set_niter(int iter);
- // chose your style
- void set_done_char(const std::string& sym) { done_char = sym; }
- void set_todo_char(const std::string& sym) { todo_char = sym; }
- void set_opening_bracket_char(const std::string& sym) { opening_bracket_char = sym; }
- void set_closing_bracket_char(const std::string& sym) { closing_bracket_char = sym; }
- // to show only the percentage
- void show_bar(bool flag = true) { do_show_bar = flag; }
- // main function
- void update();
- void update(int n);
- // default style
- void setDefaultStyle();
-
- private:
- std::string m_type;
- int progress;
- int n_cycles;
- int last_perc;
- bool do_show_bar;
- bool update_is_called;
-
- std::string done_char;
- std::string todo_char;
- std::string opening_bracket_char;
- std::string closing_bracket_char;
- };
-
- progressbar::progressbar()
- : progress(0),
- m_type(GREEN),
- n_cycles(0),
- last_perc(0),
- do_show_bar(true),
- update_is_called(false),
- done_char("#"),
- todo_char(" "),
- opening_bracket_char("["),
- closing_bracket_char("]") {}
-
- progressbar::progressbar(const std::string& type, int n, bool showbar)
- : progress(0),
- m_type(type),
- n_cycles(n),
- last_perc(0),
- do_show_bar(showbar),
- update_is_called(false),
- done_char("#"),
- todo_char(" "),
- opening_bracket_char("["),
- closing_bracket_char("]") {}
-
- void progressbar::reset() {
- progress = 0, update_is_called = false;
- last_perc = 0;
- return;
- }
-
- void progressbar::set_niter(int niter) {
- if (niter <= 0)
- throw std::invalid_argument("progressbar::set_niter: number of iterations null or negative");
- n_cycles = niter;
- return;
- }
-
- void progressbar::update() {
- if (n_cycles == 0)
- throw std::runtime_error("progressbar::update: number of cycles not set");
-
- if (!update_is_called) {
- if (do_show_bar == true) {
- std::cout << m_type << ":" << opening_bracket_char;
- for (int _ = 0; _ < 50; _++)
- std::cout << todo_char;
- std::cout << closing_bracket_char << " 0%";
- } else
- std::cout << "0%";
- }
- update_is_called = true;
-
- // compute percentage, if did not change, do nothing and return
- int perc = progress * 100. / (n_cycles - 1);
- if (perc < last_perc)
- return;
-
- // update percentage each unit
- if (perc == last_perc + 1) {
- // erase the correct number of characters
- if (perc <= 10)
- std::cout << "\b\b" << perc << '%';
- else if (perc > 10 and perc < 100)
- std::cout << "\b\b\b" << perc << '%';
- else if (perc == 100)
- std::cout << "\b\b\b" << perc << '%';
- }
- if (do_show_bar == true) {
- // update bar every ten units
- if (perc % 2 == 0) {
- // erase closing bracket
- std::cout << std::string(closing_bracket_char.size(), '\b');
- // erase trailing percentage characters
- if (perc < 10)
- std::cout << "\b\b\b";
- else if (perc >= 10 && perc < 100)
- std::cout << "\b\b\b\b";
- else if (perc == 100)
- std::cout << "\b\b\b\b\b";
-
- // erase 'todo_char'
- for (int j = 0; j < 50 - (perc - 1) / 2; ++j) {
- std::cout << std::string(todo_char.size(), '\b');
- }
-
- // add one additional 'done_char'
- if (perc == 0)
- std::cout << todo_char;
- else
- std::cout << done_char;
-
- // refill with 'todo_char'
- for (int j = 0; j < 50 - (perc - 1) / 2 - 1; ++j)
- std::cout << todo_char;
-
- // readd trailing percentage characters
- std::cout << closing_bracket_char << ' ' << perc << '%';
- if (perc == 100)
- std::cout << std::endl;
- }
- }
- last_perc = perc;
- ++progress;
- std::cout << std::flush;
-
- return;
- }
-
- void progressbar::update(int n) {
- for (int i = 0; i < n; i++) {
- update();
- }
- }
-
- void progressbar::setDefaultStyle() {
- set_todo_char(" ");
- set_done_char("*");
- set_opening_bracket_char("[");
- set_closing_bracket_char("]");
- }
-
- #endif

测试代码test.cpp:
- #include <unistd.h>
-
- #include "progressbar.hpp"
-
- int main(int argc, char* argv[]) {
- progressbar bar;
- bar.set_niter(60);
- bar.setDefaultStyle();
- for (size_t i = 0; i < 60; i++) {
- // if ((i % 20) == 0) {
- // bar.reset();
- // }
- bar.update();
- sleep(1);
- }
- return 0;
- }

编译:g++ ./test.cpp -o main, 运行./main, 结果输出:
还有点小问题是:输出*不连续,暂时未发现问题在哪里,待修改。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。