#include <algorithm>
#include <cctype>
#include <iomanip>
#include <iostream>
#include <map>
#include <string>
#include <queue>
inline bool isWordLetter(char c)
{
return std::isalnum(c) || c == '_';
}
inline void skipws(std::queue<char>& q)
{
while (!( q.empty() || isWordLetter(q.front()) ))
q.pop();
}
/* Extracts valid word.
* Returns word or empty string if no word found till the end of queue
*/
std::string extractWord(std::queue<char>& q)
{
std::string word;
bool again = false;
do {
again = false;
skipws(q);
/* Extract all consequent word character */
while( !q.empty() && isWordLetter(q.front()) ) {
word += q.front();
q.pop();
}
/* Check if word extracted is actually word */
if (word.size() < 2 || count_if(word.begin(), word.end(), isalpha) == 0) {
word.clear();
if ( !q.empty() )
again = true;
}
} while (again); //Repeat until we find word or exhaust our queue
std::transform(word.begin(), word.end(), word.begin(), tolower);
return word;
}
std::string getEnvString()
{
extern char **environ; // needed to access your execution environment
std::string envstr;
int k = -1;
while (environ[++k] != NULL) {
envstr += environ[k];
envstr += '\n';
}
return envstr;
}
int main()
{
std::string envstr = getEnvString();
std::cout << envstr << std::endl;;
std::queue<char> line( {envstr.begin(), envstr.end()} );
size_t wordCount = 0;
std::map<std::string, unsigned> entries;
std::string word;
while((word = extractWord(line)) != "" ) {
++wordCount;
++entries[word];
}
std::cout << "There is " << wordCount << " words in envstring\n" <<
"Unique words and their frequency:\n";
for(auto& p: entries) {
std::cout << std::setw(30) << p.first << ' ' << p.second << '\n';
}
}