#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstdio>
#include <hash_map>

int main( int argc, char* argv[] )
{
	int w_total = 0;
	int l_total = 0;
	int c_total = 0;
	std::hash_map< std::string, int > dictionary;
  
	printf("   lines   words   bytes file\n" );
	for ( int i = 1; i < argc; ++i )
	{
		FILE* fp = fopen(argv[i], "r");
		fseek(fp, 0, SEEK_END);
		int len = ftell(fp);
		fseek(fp, 0, SEEK_SET);
		std::string input(len, '\0');
		fread(const_cast<char*>(input.c_str()), 1, len, fp);

		int w_cnt = 0;
		int l_cnt = 0;
		int c_cnt = 0;
		bool inword = false;
		int wstart = 0;
		for ( unsigned int j = 0; j < input.length(); j++ )
		{
			char c = input[j];
			if (c == '\n')
				++l_cnt;
			if (c >= '0' && c <= '9')
			{
			}
			else if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
			{
				if (!inword)
				{
					wstart = j;
					inword = true;
					++w_cnt;
				}
			}
			else if (inword)
			{
				std::string word = input.substr( wstart, j - wstart );
				std::hash_map< std::string, int >::iterator it = dictionary.find( word );
				if ( it == dictionary.end() )
					dictionary[word] = 1;
				else
					++it->second;
				inword = false;
			}
			++c_cnt;
		}

		if (inword)
		{
			std::string w = input.substr( wstart );
			std::hash_map< std::string, int >::iterator it = dictionary.find( w );
			if ( it == dictionary.end() )
				dictionary[w] = 1;
			else
				++it->second;
		}

		printf("%d\t%d\t%d\t %s\n", l_cnt, w_cnt, c_cnt, argv[i]);
		l_total += l_cnt;
		w_total += w_cnt;
		c_total += c_cnt;
	}
  
	if (argc > 2)
	{
		printf("--------------------------------------\n%d\t%d\t%d\t total",
			   l_total, w_total, c_total);
	}
  
	printf("--------------------------------------\n");
	for( std::hash_map< std::string, int >::const_iterator cit =
			 dictionary.begin(), cend_it = dictionary.end(); cit != cend_it; ++cit )
		printf( "%d %s\n", cit->second, cit->first.c_str() );
}
