#include "stdafx.h"

#include <math.h>     // Fuer log10() (Logarithmus)
#include <iostream>
#include <iomanip>    // Fuer setw() (ostream-Feldbreite einstellen)
#include <ctype.h>    // Fuer isprint() etc. (character types)

using namespace std;

int main() {
   unsigned int const ANZAHL_ZEICHEN = 256;   // Die Anzahl der unterschiedlichen Zeichen.
   unsigned int  gezaehlteZeichen[ANZAHL_ZEICHEN];// Fuer jedes Zeichen ein Zaehler
   // Zusammenfassend:
   unsigned int  anzahlBuchstaben = 0;// Buchstaben
   unsigned int  anzahlWhitespace = 0;// Leerzeichen etc.
   char gelesenesZeichen; // Das zuletzt gelesene Zeichen
   unsigned int  maximaleHaeufigkeit = 0;


   for(unsigned int zeichenIndex = 0   // Initialisiere alle Zaehler mit 0.
          ; zeichenIndex < ANZAHL_ZEICHEN
          ; ++zeichenIndex) {
      gezaehlteZeichen[zeichenIndex] = 0;
   }

   cin.get(gelesenesZeichen);   // Lese die Eingabe und erhoehe die entsprechenden Zaehler.
   while (!cin.eof()) {
      ++gezaehlteZeichen[(unsigned int)gelesenesZeichen];
      cin.get(gelesenesZeichen);
   }
   
   /* Breite der Zahlenausgabe fuer eine huebschere Tabelle bestimmen.
      Dabei beachten, dass log10(0) undefiniert ist. */
   for (unsigned int zeichenIndex = 0
           ; zeichenIndex < ANZAHL_ZEICHEN
           ; ++zeichenIndex) {
      if (gezaehlteZeichen[zeichenIndex] > maximaleHaeufigkeit) {
         maximaleHaeufigkeit = gezaehlteZeichen[zeichenIndex];
      }
   }
   int const BREITE_ANZAHL = (int)(log10(double((maximaleHaeufigkeit>0 ? maximaleHaeufigkeit:1 ))))+1;
   int const BREITE_CODE   = (int)(log10(double(ANZAHL_ZEICHEN>0 ? ANZAHL_ZEICHEN:1 )))+1;
   
   cout << "Die gelesenen Zeichen und ihre Anzahlen:" << endl;
   for(unsigned int zeichenIndex = 0   // Fuer jedes Zeichen den Zaehler geeignet ausgeben.
          ; zeichenIndex < ANZAHL_ZEICHEN
          ; ++zeichenIndex) {
      if (0 != gezaehlteZeichen[zeichenIndex]) {
         cout << "`";
         if ( isprint((char)zeichenIndex) ) {
            cout << (char)zeichenIndex;
         } else {
            cout << "<undruckbares Zeichen, Code "
                 << setw(BREITE_CODE) << zeichenIndex << ">";
         }
         cout << "': " << setw(BREITE_ANZAHL)
              <<gezaehlteZeichen[zeichenIndex] << endl;
         
         if ( isalpha((char)zeichenIndex) ) {
            anzahlBuchstaben += gezaehlteZeichen[zeichenIndex];
         }
         if ( isspace((char)zeichenIndex) ) {
            anzahlWhitespace += gezaehlteZeichen[zeichenIndex];
         }
      }
   }
   cout << "Anzahl Buchstaben: " << anzahlBuchstaben << endl;
   cout << "Anzahl Whitespace: " << anzahlWhitespace << endl;
   return 0;
}
