Thread: Progress bar

  1. #1
    Cogito Ergo Sum
    Join Date
    Mar 2007
    Location
    Sydney, Australia
    Posts
    463

    Progress bar

    Is there anyway to get a progress bar in a console application like Cygwin??
    If not, is it possible to at least get a percentage runner. like whenever a task is done, the percentage is updated, a better implementation than:

    Code:
    if () {
     
        printf("10%\n");
     
    }
    
    if() {
    
       printf("20%\n");
    
    }

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Code:
    int x;
    for(x = 0; x<100; x++)
    {
       printf("\b\b&#37;02d%%",x);
       Sleep(1000);
    }
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Cogito Ergo Sum
    Join Date
    Mar 2007
    Location
    Sydney, Australia
    Posts
    463
    what is \b ? and also what library do i need to include for 'sleep' ?

  4. #4
    Cogito Ergo Sum
    Join Date
    Mar 2007
    Location
    Sydney, Australia
    Posts
    463
    Nvm I got that running, but it's doing nothing...I changed it from 1000 to 10 and still it does nothing :S

  5. #5
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    603
    Not sure why the use of sleep here. Try this. You can even place this in its own function if you like

    Code:
    int x;
        
        double numtasks = 76;
        double taskcompleted = 10;
        
        double percentage = (taskcompleted / numtasks) * 100;
        
        for(x = 0; x < percentage; x++)
        {
            printf("|");
               
        }
           printf(" &#37;.2f%%\n", percentage);
        return (EXIT_SUCCESS);

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You may also find that printf() is buffering if you don't use "\n" on the end of the string, which means that you need fflush(stdout) to force the printed stuff to be shown on the console.

    Using '\r' instead of '\b' will take the cursor to the beginning of the line no matter how long it is (which is useful for example if you want to show what file is being copied when copying a bunch of files, etc).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Here is the working example
    Code:
    #include <stdio.h>
    #include <windows.h>
    int main(void)
    {
    	int x;
    	for(x = 0; x<100; x++)
    	{
    	   printf("\b\b\b&#37;02d%%",x);
    	   Sleep(1000);
    	}
    }
    windows.h is for Sleep
    Sleep is for emulating delay between sequential printf

    \b removes last printed character
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  8. #8
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    603
    Quote Originally Posted by matsp View Post
    You may also find that printf() is buffering if you don't use "\n" on the end of the string, which means that you need fflush(stdout) to force the printed stuff to be shown on the console.

    Using '\r' instead of '\b' will take the cursor to the beginning of the line no matter how long it is (which is useful for example if you want to show what file is being copied when copying a bunch of files, etc).

    --
    Mats
    Thanks for the hint on '\r' and fflush! Was interested in this as well. So thought I would have a try at this code. Below works pretty well.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int show_status (double x);
    
    int main()
    {
        int taskcompleted = 0;
        double numtasks = 76;
             
        for(; taskcompleted <= numtasks; taskcompleted++)
        {
           show_status((taskcompleted / numtasks) * 100);
        }
        
       return (EXIT_SUCCESS);    
        
    }
    
    int show_status (double percent)
    {
        int x;
        for(x = 0; x < percent; x++)
        {   
           printf("|");
                  
        }
           printf("%.2f%%\r", percent);
           fflush(stdout);
           system("sleep 1");
          
        
        return(EXIT_SUCCESS);
    }

  9. #9
    Cogito Ergo Sum
    Join Date
    Mar 2007
    Location
    Sydney, Australia
    Posts
    463
    Thanks for all that guys, interesting stuff

  10. #10
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Note: printing a '\b' is like typing backspace, except the character isn't erased. If you want it to be erased, you can use something like this:
    Code:
    printf("\b \b");
    The space writes over whatever character was printed there previously.

    Another thing: if you print \r after some text, then something else printed later could overwrite it. In other words, something like this looks strange:
    Code:
    printf("Hello, World!\r");
    printf("Error\n");
    In general, I find it's better to print the \r first:
    Code:
    printf("\rHello, World!");
    This method also has the advantage that the cursor appears after the text, as you'd expect, rather than at the beginning of the line.

    Also note that neither '\b' nor '\r' can go back a line. Once you print a newline ('\n'), you can no longer edit that line.

    Finally, here's my stab at it:
    Code:
    #include <stdio.h>
    #include <time.h>
    
    void twirlybar(void) {
        static clock_t last = 0;
        static const char *dir = "|/-\\";
        static size_t angle = 0;
        clock_t now;
        
        now = clock();
        if((now - last) / (CLOCKS_PER_SEC / 10.0) >= 0.5) {
            if(++angle == sizeof(dir)/sizeof(*dir)) angle = 0;
    	last = now;
        }
    
        putchar('\b');
        putchar(dir[angle]);
        fflush(stdout);
    }
    
    int main(void) {
        for(;;) twirlybar();
    
        return 0;
    }
    (Code highlighted with codeform.) Of course, it would be better to use time_t in a real application, because clock() might be called by something else. And there are far too many static variables in it, passing them in would be a better idea . . . .
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Updating a progress bar
    By NewGuy100 in forum C++ Programming
    Replies: 2
    Last Post: 03-13-2006, 01:00 PM
  2. beach bar (sims type game)
    By DrKillPatient in forum Game Programming
    Replies: 1
    Last Post: 03-06-2006, 01:32 PM
  3. Is comctl32.lib required for progress bar controls?
    By JasonD in forum Windows Programming
    Replies: 4
    Last Post: 08-28-2004, 02:30 PM
  4. progress bar newbie
    By WaterNut in forum Windows Programming
    Replies: 18
    Last Post: 08-09-2004, 01:42 PM
  5. File Through Winsock & Progress on bar
    By (TNT) in forum Windows Programming
    Replies: 4
    Last Post: 12-05-2001, 10:50 PM