- Main Page
- Namespaces
- Classes
- Files

# word_count.cpp

Go to the documentation of this file.

    00001
    00003 #include <iomanip>
    00004 #include <ios>
    00005 #include <iostream>
    00006 #include <istream>
    00007 #include <locale>
    00008 #include <map>
    00009 #include <ostream>
    00010 #include <string>
    00011
    00012 typedef std::map<std::string, int>  count_map;
    00013 typedef count_map::iterator         count_iter;
    00014 typedef std::string::size_type      str_size;
    00015
    00021 void initialize_streams()
    00022 {
    00023   std::cin.imbue(std::locale());
    00024   std::cout.imbue(std::locale());
    00025 }
    00026
    00031 str_size get_longest_key(count_map map)
    00032 {
    00033   str_size result(0);
    00034   for (count_iter iter(map.begin()); iter != map.end(); ++iter)
    00035     if (iter->first.size() > result)
    00036       result = iter->first.size();
    00037   return result;
    00038 }
    00039
    00047 void print_pair(count_iter iter, str_size longest)
    00048 {
    00049   const int count_size(10); // Number of places for printing the count
    00050   std::cout << std::setw(longest)    << std::left  << iter->first <<
    00051                std::setw(count_size) << std::right << iter->second << '\n';
    00052 }
    00053
    00057 void print_counts(count_map counts)
    00058 {
    00059   str_size longest(get_longest_key(counts));
    00060
    00061   // For each word/count pair...
    00062   for (count_iter iter(counts.begin()); iter != counts.end(); ++iter)
    00063     print_pair(iter, longest);
    00064 }
    00065
    00069 class function
    00070 {
    00071 public:
    00073   function(std::locale loc) : locale_(loc) {}
    00077   bool isalnum(char ch) const { return std::isalnum(ch, locale()); }
    00082   char tolower(char ch) const { return std::tolower(ch, locale()); }
    00083 private:
    00084   std::locale const& locale() const { return locale_; }
    00085   std::locale locale_;
    00086 };
    00087
    00089 class non_letter : public function
    00090 {
    00091 public:
    00093   non_letter(std::locale loc) : function(loc) {}
    00097   bool operator()(char ch)
    00098   const
    00099   {
    00100     return not isalnum(ch);
    00101   }
    00102 };
    00103
    00108 class lowercase : public function
    00109 {
    00110 public:
    00112   lowercase(std::locale loc) : function(loc) {}
    00117   char operator()(char ch)
    00118   const
    00119   {
    00120     return tolower(ch);
    00121   }
    00122 };
    00123
    00125 class sanitizer : public function
    00126 {
    00127 public:
    00129   sanitizer(std::locale loc) : function(loc), non_letter_(loc), lowercase_(loc) {}
    00133   std::string operator()(std::string str)
    00134   {
    00135     // Remove all non-letters from the string, and then erase them.
    00136     str.erase(std::remove_if(str.begin(), str.end(), non_letter_), str.end());
    00137
    00138     // Convert the remnants of the string to lowercase.
    00139     std::transform(str.begin(), str.end(), str.begin(), lowercase_);
    00140
    00141     return str;
    00142   }
    00143 private:
    00144   non_letter non_letter_;
    00145   lowercase lowercase_;
    00146 };
    00147
    00149 int main()
    00150 {
    00151   // Fetch the native locale only once.
    00152   std::locale native(std::locale(""));
    00153   // Use the native locale as the global locale.
    00154   std::locale::global(native);
    00155   initialize_streams();
    00156
    00157   count_map counts;
    00158   std::string word;
    00159   sanitizer sanitize(native);
    00160
    00161   // Read words from the standard input and count the number of times
    00162   // each word occurs.
    00163   while (std::cin >> word)
    00164   {
    00165     std::string copy(sanitize(word));
    00166
    00167     // The "word" might be all punctuation, so the copy would be empty.
    00168     // Don't count empty strings.
    00169     if (not copy.empty())
    00170       ++counts[copy];
    00171   }
    00172
    00173   print_counts(counts);
    00174 }