큰 파일을 다운로드하기 위해 C ++로 콘솔 프로그램을 작성하고 있습니다. 파일 크기를 알고 있으며 작업 스레드를 시작하여 다운로드합니다. 더 멋지게 보이도록 진행률 표시기를 표시하고 싶습니다.
cout 또는 printf에서 다른 시간에 동일한 위치에 다른 문자열을 표시하는 방법은 무엇입니까?
답변
줄 바꿈 (\ n)없이 “캐리지 리턴”(\ r)을 사용할 수 있으며 콘솔이 올바른 작업을 수행하기를 바랍니다.
답변
출력의 고정 너비로 다음과 같이 사용하십시오.
float progress = 0.0;
while (progress < 1.0) {
int barWidth = 70;
std::cout << "[";
int pos = barWidth * progress;
for (int i = 0; i < barWidth; ++i) {
if (i < pos) std::cout << "=";
else if (i == pos) std::cout << ">";
else std::cout << " ";
}
std::cout << "] " << int(progress * 100.0) << " %\r";
std::cout.flush();
progress += 0.16; // for demonstration only
}
std::cout << std::endl;
[> ] 0 %
[===========> ] 15 %
[======================> ] 31 %
[=================================> ] 47 %
[============================================> ] 63 %
[========================================================> ] 80 %
[===================================================================> ] 96 %
이 출력은 서로 아래에 한 줄로 표시 되지만 터미널 에뮬레이터 (Windows 명령 줄에서도 동일)에서는 동일한 줄에 인쇄 됩니다 .
마지막에 더 많은 것을 인쇄하기 전에 개행을 인쇄하는 것을 잊지 마십시오.
끝에서 막대를 제거하려면 공백으로 덮어 써야합니다 "Done."
. 예를 들어 .
물론 printf
C 에서도 동일한 작업을 수행 할 수 있습니다 . 위의 코드를 수정하는 것은 간단해야합니다.
답변
C
진행률 표시 줄 너비를 조정할 수 있는 솔루션의 경우 다음을 사용할 수 있습니다.
#define PBSTR "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"
#define PBWIDTH 60
void printProgress(double percentage) {
int val = (int) (percentage * 100);
int lpad = (int) (percentage * PBWIDTH);
int rpad = PBWIDTH - lpad;
printf("\r%3d%% [%.*s%*s]", val, lpad, PBSTR, rpad, "");
fflush(stdout);
}
다음과 같이 출력됩니다.
75% [|||||||||||||||||||||||||||||||||||||||||| ]
답변
boost progress_display 살펴보기
http://www.boost.org/doc/libs/1_52_0/libs/timer/doc/original_timer.html#Class%20progress_display
나는 그것이 당신이 필요로하는 것을 할 수 있다고 생각하고 링크 할 것이 없기 때문에 헤더 전용 라이브러리라고 생각합니다.
답변
캐리지 리턴 문자 ( \r
)를 인쇄 하여 출력 “커서”를 현재 행의 처음으로 다시 이동할 수 있습니다 .
보다 정교한 접근 방식을 위해 ncurses (콘솔 텍스트 기반 인터페이스 용 API)와 같은 것을 살펴보십시오.
답변
이 질문에 답하는 데 조금 늦었지만 원하는 것을 정확하게 수행하는 간단한 수업을 만들었습니다 . ( using namespace std;
이전에 내가 썼다는 것을 명심 하십시오.) :
class pBar {
public:
void update(double newProgress) {
currentProgress += newProgress;
amountOfFiller = (int)((currentProgress / neededProgress)*(double)pBarLength);
}
void print() {
currUpdateVal %= pBarUpdater.length();
cout << "\r" //Bring cursor to start of line
<< firstPartOfpBar; //Print out first part of pBar
for (int a = 0; a < amountOfFiller; a++) { //Print out current progress
cout << pBarFiller;
}
cout << pBarUpdater[currUpdateVal];
for (int b = 0; b < pBarLength - amountOfFiller; b++) { //Print out spaces
cout << " ";
}
cout << lastPartOfpBar //Print out last part of progress bar
<< " (" << (int)(100*(currentProgress/neededProgress)) << "%)" //This just prints out the percent
<< flush;
currUpdateVal += 1;
}
std::string firstPartOfpBar = "[", //Change these at will (that is why I made them public)
lastPartOfpBar = "]",
pBarFiller = "|",
pBarUpdater = "/-\\|";
private:
int amountOfFiller,
pBarLength = 50, //I would recommend NOT changing this
currUpdateVal = 0; //Do not change
double currentProgress = 0, //Do not change
neededProgress = 100; //I would recommend NOT changing this
};
사용 방법에 대한 예 :
int main() {
//Setup:
pBar bar;
//Main loop:
for (int i = 0; i < 100; i++) { //This can be any loop, but I just made this as an example
//Update pBar:
bar.update(1); //How much new progress was added (only needed when new progress was added)
//Print pBar:
bar.print(); //This should be called more frequently than it is in this demo (you'll have to see what looks best for your program)
sleep(1);
}
cout << endl;
return 0;
}
참고 : 바의 모양을 쉽게 변경할 수 있도록 모든 클래스의 문자열을 공개했습니다.
답변
또 다른 방법은 “점”또는 원하는 문자를 표시하는 것입니다. 아래 코드는 1 초 후에 진행률 표시기 [일종의 로딩 …]를 점으로 인쇄합니다.
추신 : 저는 여기서 수면을 사용하고 있습니다. 성능이 문제라면 두 번 생각하십시오.
#include<iostream>
using namespace std;
int main()
{
int count = 0;
cout << "Will load in 10 Sec " << endl << "Loading ";
for(count;count < 10; ++count){
cout << ". " ;
fflush(stdout);
sleep(1);
}
cout << endl << "Done" <<endl;
return 0;
}