Thread: Bar graph troubles

  1. #1
    Registered User
    Join Date
    Oct 2010
    Posts
    5

    Bar graph troubles

    Hello, new guy here. I've been tasked with writing a bar graph but I cannot figure out how fill in the graph without horribly messy code. It's a vertical bar graph that is passed an array. I played around a bit with if statements but that just ended up in an explosion of crap. I don't necessarily want a solution, just some help or suggestions. Thanks!

    Code:
    #include<stdio.h>
    #define PI 3.14159
    
    
    void printGraph( double milesPG[] ){
         int y=100, x=0;
         while(y!=0){y-=5; printf("%-4d", y);
                                 
         printf("    -----------------------------------\n");
         printf("    00-05 05-10 10-15 15-20 20-25 25-30\n");
    }
    Last edited by knightmare; 10-24-2010 at 10:57 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > while(y!=0)
    Within this loop, you need to loop over your array milesPG

    You need to decide for each value of y, what max value of MPG that corresponds to. If the array value is greater than that, then you draw your bar character in that position.
    Otherwise, draw a space.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    You want a horizontal bar graph or a vertical one? (looks horizontal atm).

    Each bar on the graph will have a start and a width (or depth for horizontal). Think of a table with rows and column, like graph paper. How many char's wide/deep do you want each bar to be? Each bar will start at that width * their bar #, from the left(from the top).

    Drawing it out on paper is a good way to help you "see" it. Once you see it, and have some notes (like width you want for each bar) , then you can start to make sense of it with code.

    Keep in mind that ALL lower (more to the left for horizontal) rows(cols) will have to be filled in with the fill char (X is common) you have chosen, after the value for that bar has been reached in your graph.
    Last edited by Adak; 10-24-2010 at 10:48 AM.

  4. #4
    Registered User
    Join Date
    Oct 2010
    Posts
    5
    Thank you for the suggestions. I can't really explain, so here is the example I'm supposed to be emulating:

    Code:
    45
    40
    35
    30        *****
    25        ***** *****
    20        ***** *****
    15        ***** *****
    10  ***** ***** *****
    5   ***** ***** *****
    0   ***** ***** *****
        -----------------------------------
        00-05 05-10 10-15 15-20 20-25 25-30
    I know how I can go through and check each part of the array if there should be a print out there, but I can't figure out how I can align it properly with the bottom.

    Also, is there any way I can improve how I'm printing out the bottom? I feel like my way of doing it is...lazy.

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    You need to print out what units are being represented by the numbers we're seeing here. These numbers mean nothing, as is.

    The bottom row is lazy, but that's good. Looks could be improved a bit, but that's a last detail.

    Get a sample of the data posted up, so we can talk about specifics. Doesn't need to be your project's data, just similar data.

  6. #6
    Registered User
    Join Date
    Oct 2010
    Posts
    5
    Ok, here's a link to what I have so far and the sample txt I'm reading from: http://dl.dropbox.com/u/10771960/fuelgraph.zip

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Some questions for you:

    1) Why are you dividing min by 5 in the program?

    2) how is time to be represented in the bar graph? Are those to be 5 second intervals, on the bottom of the graph, with mpg on the far left side?

    3) Why are you dividing distance traveled, by 63360? The equation I'm familiar with is:
    mpg = distance/gas consumed

    4) Have you confirmed that your math for this, is correct?

    5) Why 301?
    Code:
    for(i=1;i != 301;i++) {
      //etc.
    }
    Last edited by Adak; 10-24-2010 at 08:32 PM.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This is a very basic template for printing out a bar graph, in your program:

    Code:
    #include<stdio.h>
    
    #define PI 3.14159
    #define ROWS 10
    #define COLS 30
    
    void printGraph(void);
    
    int main(){
        
        int min, inches, c=0, i, flength;
        double totalRev=0, totalGas=0, rev, gas;
        char file[20];
        FILE *fp;
    
        printGraph();
    /*
        //printf("What file stores the car data?\n");
        //scanf("%s", &file); printf("\n");
        
        strcpy(file, "fuelsampl.txt");    
        flength = strlen(file);
        if(file[flength-1]=='\n')
          file[flength-1]='\0';
    
        if((fp = fopen(file, "r"))==NULL) {
          printf("\nError opening input file\n");
          return 1;
        }
        
        fscanf(fp, "%d", &min);
        fscanf(fp, "%d", &inches);
        
        min = min/5;
        double mpg[min];
    
        while(c<min) {
          for(i=1;i!=301;i++) {
            fscanf(fp, "%lf%lf", &rev, &gas);
            totalRev+=rev, totalGas+=gas;
          }
          mpg[c] = ( (PI * inches * 2 * totalRev) / 63360 ) / totalGas;
          c++;
          totalRev=0, totalGas=0; 
        }
        
        //printGraph( mpg );
                    
       // c=0;            
       // while(c<=(min-1)){printf("%lf\t", mpg[c]); c++;}
        //printf("%d", min);
    
    
        fclose(fp);
    */
        printf("\n\n\t\t\t    press enter when ready");
        (void) getchar();
        return 0;
    }
    void printGraph(void) {
      int i,r,c,n, width=5, twidth=35, theight=10;
      //int y=100;
      char dat[ROWS][COLS]; 
    
      for(r=0,n=0;r<ROWS;r++) {
        for(c=0;c<COLS;c++) {
          dat[r][c]=' ';                       //just loads some char's
          ++n;                                  //into the array, to show
          if(n-127<r)
            dat[r][c]='*';                  //for a demo
        }
      }
    
      //basic print out block
      for(r=ROWS-1,n=45;r>-1;r--) {
        printf(" %2d| ", n);
        for(c=0;c<COLS;c++) {
          if(c % width == 0 && c) 
            putchar(' ');
          printf("%c",dat[r][c]);
    
        }
        putchar('\n');
        n-=5;
      }
                                //while(y!=0){y-=5; printf("%-4d", y);}
                     
      printf("     -----------------------------------\n");
      printf("     00-05 05-10 10-15 15-20 20-25 25-30\n");
    
    }
    All this does is print out a bar graph. You've gone on vacation?

    Edit: demo output:
    ============
    Code:
     45|                                    
     40|                                    
     35|                                    
     30|                                    
     25|                                    
     20| ***** *****                        
     15| ***** ***** ***** ***** ***** *****
     10| ***** ***** ***** ***** ***** *****
      5| ***** ***** ***** ***** ***** *****
      0| ***** ***** ***** ***** ***** *****
         -----------------------------------
         00-05 05-10 10-15 15-20 20-25 25-30
    
    
    			    press enter when ready
    Last edited by Adak; 10-25-2010 at 02:12 AM.

  9. #9
    Registered User
    Join Date
    Oct 2010
    Posts
    5
    Quote Originally Posted by Adak View Post
    Some questions for you:

    1) Why are you dividing min by 5 in the program?

    2) how is time to be represented in the bar graph? Are those to be 5 second intervals, on the bottom of the graph, with mpg on the far left side?

    3) Why are you dividing distance traveled, by 63360? The equation I'm familiar with is:
    mpg = distance/gas consumed

    4) Have you confirmed that your math for this, is correct?

    5) Why 301?
    Code:
    for(i=1;i != 301;i++) {
      //etc.
    }
    1) Dividing by five because the graph presents information in intervals of five. Dividing by five gives me how many times I need to check the .txt file.

    2) The bottom of the graph is five minute intervals.

    3) Can't remember off the top of my head but that equation involves tire radius and revolutions. It's more than just distance and gas used.

    4) Yes my math is correct.

    5) The .txt file stores information about a car per second. Because I need information in five minute intervals, I need to add up 300 seconds worth of information.

    Everything works as necessary except for the actual printing of the graph bit.

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Your program only provides 3 numbers into the mpg array. (min = 3).

    This is the output given the following mpg array numbers:

    Code:
    
     10.033465
     32.441399
     28.829947
    
     45|                               
     40|                               
     35|                               
     30|       *****                   
     25|       ***** *****             
     20|       ***** *****             
     15|       ***** *****             
     10| ***** ***** *****             
      5| ***** ***** *****             
      0| ***** ***** *****             
         -----------------------------------
         00-05 05-10 10-15 15-20 20-25 25-30
    Press any key to continue . . .

    and this is the tweaked version that did that:

    Code:
    #include<stdio.h>
    
    #define PI 3.14159
    #define MIN 300
    #define ROWS 10
    #define COLS 30
    
    
    void printGraph(double milesPG[], int min) {
        int i,j,r,c,n; 
        double num=0.0;
        char dat[ROWS][COLS]; 
    
        for(i=0;i<ROWS;i++) {   //set all dat elements to spaces
          for(j=0;j<COLS;j++)
            dat[i][j]=' ';
        }
        /* data[][] assignment block */
        printf("\n\n\n");
        for(i=0,c=0;i<min;i++) {  
          printf("\n %lf", milesPG[i]);
          num=milesPG[i]/5;        //to match vertical graduations
          for(j=0;j<num;j++) {
            dat[j][c]='*';
            dat[j][c+1]='*';
            dat[j][c+2]='*';
            dat[j][c+3]='*';
            dat[j][c+4]='*';
          }
          c+=6;
        }
    
      //print out block
      printf("\n\n");
      for(r=ROWS-1,n=45;r>-1;r--) {
        printf(" %2d| ", n);
        for(c=0;c<COLS;c++) {
          printf("%c",dat[r][c]);
        }
        putchar('\n');
        n-=5;
      }
      printf("     -----------------------------------\n");
      printf("     00-05 05-10 10-15 15-20 20-25 25-30\n");
    
    }
    
    int main(){
        
        int min, inches, c=0, i, flength;
        double totalRev=0, totalGas=0, rev, gas;
        char file[20];
        FILE *fp;
        double mpg[MIN];
    
        printf("\n\n\n");
        printf("What file stores the car data?\n");
        scanf("%s", &file); printf("\n");
    
        /* for IDE debug only
        strcpy(file, "fuelmpg.txt");    //for debug in IDE only
        flength = strlen(file);
        if(file[flength-1]=='\n')       // ditto
          file[flength-1]='\0';
        */
    
        fp = fopen(file, "r");
        if(fp==NULL) {
          printf("\nError opening %s\n", file);
          return 1;
        }
        fscanf(fp, "%d", &min);
        fscanf(fp, "%d", &inches);
        
        min = min/5;
        while(c<=(min-1)){
                    for(i=1;i!=301;i++){
                            fscanf(fp, "%lf%lf", &rev, &gas);
                            totalRev+=rev, totalGas+=gas;
                            }
                    mpg[c] = ( PI * inches * 2 * totalRev / 63360 ) / totalGas;
                    c++;
                    totalRev=0, totalGas=0;
                    }
        
      printGraph(mpg, min);
      fclose(fp);
      (void) getchar();
      system("PAUSE");
      return 0;
    }

  11. #11
    Registered User
    Join Date
    Oct 2010
    Posts
    5
    Thank you for your help! Using your advice I thought up how to get what I needed. Here's how I did it:

    Code:
    void printGraph( double milesPG[], int min ){ //gets passed mpg array and array length; prints graph
         int y=100, c, x;
         while(y!=0){y-=5; printf("%-4d", y); //prints left side
         
             for(c=0;c<=(min-1);c++){ //runs through the array
                for(x=0;x<5;x++){ //decides whether to print star or spaces
                   if(milesPG[c]>=y)
                     putchar('*');
                   else
                     putchar(' ');}
                     
             putchar(' ');}
                     
             putchar('\n');}
                 
                     
         printf("    -----------------------------------\n");
         printf("    00-05 05-10 10-15 15-20 20-25 25-30\n");
    }

  12. #12
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Using y to test the value is smart - well done!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to create graph and bar char
    By beon in forum Windows Programming
    Replies: 1
    Last Post: 07-25-2007, 11:45 PM
  2. error help making no sense
    By tunerfreak in forum C++ Programming
    Replies: 5
    Last Post: 04-17-2007, 07:55 PM
  3. beach bar (sims type game)
    By DrKillPatient in forum Game Programming
    Replies: 1
    Last Post: 03-06-2006, 01:32 PM
  4. Bar graph
    By robjules in forum C++ Programming
    Replies: 3
    Last Post: 11-28-2001, 10:55 PM
  5. Horizontal bar Graph?
    By robjules in forum C++ Programming
    Replies: 4
    Last Post: 11-26-2001, 04:55 PM