/* * Compute a histogram of the bytes in the input file. Each byte is * printed numerically and as an ASCII character (if it is one). */ #include #include #include #include using namespace std; /* * 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 using an appropriate form. */ // Check the range to see the type of character. 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, // or uses some non-ASCII encoding. Just put spaces. cout << " "; else // An actual character. cout << (char)chcode << " "; // Print the count. cout << " " << setw(cntdigits) << count << " "; // 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 = (int)((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. for(int & c: hist) { c = 0; } // 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 = (int)(log10((float)maxct) + 1.00001); // Print the histogram. for(int m = 0; m < HISSIZE; ++m) prhistline(m, hist[m], maxct, cntdigits); }