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 }

Generated on Sun Nov 30 09:53:23 2008 for Exploring C++ - Final Forms of Key Examples by  doxygen 1.5.3