|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
由于在控制台中只能以打印字符的形式来进行输出,很多时候我们在运行比较大的程序时无法知道完成进度,所以写了一个类来实现这一功能。
- //DosProgressBar header file
- //"DosProgressBar"用于在控制台中实现进度显示
- //版本号: 1.0.1
- //作者:三点一洲
- #pragma once
- #include <cstring>
- #include <cstdio>
- #include <string>
- #include <iostream>
- #include <windows.h>
- #define __ARR_CAPACITY 100
- #define _INIT_VALUE 0
- #define _MAX_VALUE 1
- #define _PERCENT_MULTI 100
- #define _BLOCK_NUMBERS 32
- #define _DEFAULT_FLUSH_FREQUENCY 65536
- #define _FLUSH_FREQUENCY 3
- #define _FILL_BLOCK "█"
- #define _STANDEARD_OUT_SIZE (_BLOCK_NUMBERS * 2 + 2)
- #define _UNUSED_BAR 0
- #define _USING_BAR 1
- #define _USED_BAR 2
- //设置光标位置(x, y)
- void gotoxy(short, short);
- //设置光标位置(COORD)
- void gotoxy(COORD);
- //返回当前光标位置
- COORD wherexy();
- //获取光标的位置y
- int wherey();
- //获取光标的位置x
- int wherex();
- //计算合适的刷新频率
- int calcFrequency(int);
- class DosProgressBar
- {
- typedef int bar_status;
- typedef double progress_value;
- private:
- progress_value nowValue;
- bar_status status;
- COORD outPos;
- int flushCount;
- int flushFrequency;
- public:
- //格式化进度
- inline std::string percentFormate()
- /* 格式化当前进度 */
- {
- char s[__ARR_CAPACITY];
- sprintf(s, "%.2f%%", nowValue * _PERCENT_MULTI);
- //std::cout<<std::string(s)+"\n";
- return std::string(s);
- }
- //设置当前进度
- inline progress_value setNowValue(progress_value pv)
- /* 设置进度值 */
- {
- nowValue = pv;
- return pv;
- }
- //获得当前进度
- inline progress_value getNowValue()
- /* 获得当前进度 */
- {
- return nowValue;
- }
- private:
- //int printProgressBar(const char end = '\0');
- /* 按频率打印出进度条 */
- //int printProgressBar(const std::string &, const char end = '\0');
- /* 按频率打印出有后缀进度条 */
- //回退到开始光标
- void backToStartPos();
- //立即打印进度条
- int printProgressBarSoon(const char end = '\0');
- //立即打印有后缀进度条
- int printProgressBarSoon(const std::string &, const char end = '\0');
- public:
- //刷新进度条
- void flushProgressBar(progress_value);
- //重置进度条
- void reSetBar();
- //设置合理刷新频率
- void setFrequency(int);
- public:
- inline DosProgressBar(void) : nowValue(0), flushCount(0), outPos({0, 0}), status(_UNUSED_BAR), flushFrequency(_DEFAULT_FLUSH_FREQUENCY)
- {
- }
- inline DosProgressBar(progress_value _nowValue) : nowValue(_nowValue), flushCount(0), outPos({0, 0}), status(_UNUSED_BAR), flushFrequency(_DEFAULT_FLUSH_FREQUENCY)
- {
- }
- ~DosProgressBar(void) {}
- };
复制代码
- //DosProgressBar source file
- //"DosProgressBar"用于在控制台中实现进度显示
- //版本号: 1.0.1
- //作者:三点一洲
- #include "DosProgressBar.h"
- #include <cmath>
- //获取光标的位置x
- int wherex()
- {
- CONSOLE_SCREEN_BUFFER_INFO pBuffer;
- GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &pBuffer);
- return pBuffer.dwCursorPosition.X;
- }
- //获取光标的位置y
- int wherey()
- {
- CONSOLE_SCREEN_BUFFER_INFO pBuffer;
- GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &pBuffer);
- return pBuffer.dwCursorPosition.Y;
- }
- //返回当前光标位置
- COORD wherexy()
- {
- COORD _coord;
- CONSOLE_SCREEN_BUFFER_INFO pBuffer;
- GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &pBuffer);
- _coord.X = pBuffer.dwCursorPosition.X;
- _coord.Y = pBuffer.dwCursorPosition.Y;
- return _coord;
- }
- //设置光标位置(x, y)
- void gotoxy(short x, short y)
- {
- COORD pos = {x, y};
- HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
- SetConsoleCursorPosition(hOut, pos);
- }
- //设置光标位置(COORD)
- void gotoxy(COORD _coord)
- {
- COORD pos = _coord;
- HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
- SetConsoleCursorPosition(hOut, pos);
- }
- //计算合适的刷新频率
- int calcFrequency(int _t)
- {
- int t = (int)(_t / _BLOCK_NUMBERS / ((int)(log( _t < exp(2) ? exp(2) : _t ) / 2)) + 1);
- return t;
- }
- //回退到开始光标
- void DosProgressBar::backToStartPos()
- {
- gotoxy(outPos);
- return;
- }
- //立即打印进度条
- int DosProgressBar::printProgressBarSoon(const char end)
- {
- std::string outs("|");
- int block = (int)(nowValue * _BLOCK_NUMBERS);
- for (int i = 0; i < block; i++)
- {
- outs += _FILL_BLOCK;
- }
- outs += std::string(_STANDEARD_OUT_SIZE - 2 - block * 2, ' ');
- outs += "|";
- outs += " " + percentFormate();
- if (end != '\0')
- outs += end;
- return printf("%s", outs.c_str());
- }
- //立即打印有后缀进度条
- int DosProgressBar::printProgressBarSoon(const std::string &suffix, const char end)
- {
- int n = printProgressBarSoon('\0') + printf("%s", suffix.c_str());
- if (end != '\0')
- return n + printf("%c", end);
- else
- return n;
- }
- //刷新进度条
- void DosProgressBar::flushProgressBar(progress_value pv)
- {
- if (status == _UNUSED_BAR)
- {
- //std::cout<<"\n"<<flushFrequency<<std::endl;
- status = _USING_BAR;
- COORD _co = wherexy();
- if (_co.X > 0)
- {
- _co.Y++;
- _co.X = 0;
- }
- outPos = _co;
- gotoxy(outPos);
- }
- else if (status == _USED_BAR)
- {
- std::cerr << "进度条已使用,请重置后继续使用" << std::endl;
- //exception 1
- //exit(0);
- }
- setNowValue(pv);
- ++flushCount;
- int resetFlag = flushCount / flushFrequency;
- flushCount %= flushFrequency;
- if (resetFlag || nowValue == 1.0)
- {
- gotoxy(outPos);
- printProgressBarSoon('\n');
- if (!(nowValue == 1.0))
- {
- gotoxy(outPos);
- }
- else
- {
- status = _USED_BAR;
- }
- }
- }
- //重置进度条
- void DosProgressBar::reSetBar()
- {
- }
- //设置合理刷新频率
- void DosProgressBar::setFrequency(int total)
- {
- flushFrequency = calcFrequency(total);
- return;
- }
复制代码
- #include "DosProgressBar.h"
- #define N 100000000 //总循环次数
- int main()
- {
- DosProgressBar dpb(0.0);
- dpb.setFrequency(N);
- for (int i = 0; i <= N ; i++)
- {
- dpb.flushProgressBar(i * 1.0 / N);
- }
- return 0;
- }
复制代码 |
|