/* * Print one line of the histogram. It receives the character to print, * the number of times it apeared, the maximum count, and the number of * digits to display in the character count values. */ void prhistline(int chcode, int count, int maxct, int cntdigits) { // Names for the low-valued control characters of the ASCII set. string ascnames[] = { "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", "bs ", "ht ", "lf ", "vt ", "ff ", "cr ", "so ", "si ", "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", "can", "em ", "sub", "esc", "fs ", "gs ", "rs " };
// If the count is zero, omit the line. if(count == 0) return;
// Print the character code, base 16 filled with zeros to width 2. cout << "x" << setw(2) << setfill('0') << hex << chcode << " " << setfill(' ') << dec;
/* Print the character. */
// See if it is one of the ASCII control codes. if(chcode < sizeof ascnames / sizeof ascnames[0]) // Low ASCII control codes. cout << ascnames[chcode]; else if(chcode == 127) // The only high ASCII control code. cout << "del"; else if(chcode > 127) // Byte above the ASCII set. Input must be a binary file. // Just put spaces here. cout << " "; else // An actual character. cout << (char)chcode << " ";
// Print the bar. This takes the ratio of the actual count to the // maximum count, then computes that portion of the available space // as the bar length. */ int barsize = (79 - 9 - cntdigits) * ((double)count / (double)maxct) + 0.5; while(barsize--) cout << "#"; cout << endl; }
/* * Read the file and print the histogram. */
const int HISSIZE = 256; int main() { int hist[HISSIZE]; /* Count of bytes. */ int maxct = 0; /* Maximum of any count. */ int cntdigits; /* Num digits for printing count. */
// Zero out all the counts. */ memset(hist, 0, sizeof hist);
/* Read the input file and count each character. */ char inch; while(cin.get(inch)) { /* Update the count, and the maximum. */ if(++hist[inch] > maxct) maxct = hist[inch]; }
/* Compute the number of spaces needed for printing the counts */ cntdigits = log10((float)maxct) + 1.00001;
/* Print the histogram. */ for(int m = 0; m < HISSIZE; ++m) prhistline(m, hist[m], maxct, cntdigits); }