Counting words in files - follow-up-3 Previous question:

Counting words in files - follow-up 2

For simplifying the code, I have implemented std::regex rather than templates.

How can I improve this code further? 

//
//program name: WordCounter
//
//usage: C:\&gt;WordCounter.exe test.txt test1.txt 
//
#include &lt;iostream&gt;
#include &lt;iomanip&gt;
#include &lt;fstream&gt;
#include &lt;unordered_map&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;regex&gt;

using Words = std::unordered_map&lt;std::string, std::size_t&gt;;

template&lt;typename T&gt;
std::string getToken(T begin, T end, std::regex e = std::regex{ R"([^.,\n\r]+)" })
{
    std::smatch match{};

    std::string result{};

    if (std::regex_search(begin, end, match, e))
    {
        result.append(match.str());
    }

    return result;
}

bool loadFromFile(const std::string&amp; fileName, Words&amp; words)
{
    std::ifstream file(fileName);

    if (!file)
    {
        return false;
    }

    for (std::string word; file &gt;&gt; word;)
    {
        ++words[getToken(word.cbegin(), word.cend())];
    }

    return true;
}

template&lt;typename T&gt;
void showResult(const T&amp; begin, const T&amp; end)
{
    std::vector&lt;T&gt; words;

    words.reserve(std::distance(begin, end));

    for (auto i = begin; i != end; ++i)
    {
        words.push_back(i);
    }

    std::sort(words.begin(), words.end(),
        [&amp;](const T&amp; it1, const T&amp; it2)
    {
        return it1-&gt;second &gt; it2-&gt;second;
    });

    int x = 0;

    for (const auto&amp; i : words)
    {
        if (x++ == 0)
        {
            std::cout &lt;&lt; "\nThe most repeated element is: " &lt;&lt; i-&gt;first &lt;&lt; "\n\n";

            std::cout &lt;&lt; " Word\tRepeated Times";

            std::cout &lt;&lt; '\n' &lt;&lt; std::setfill('-') &lt;&lt; std::setw(23) &lt;&lt; '\n';
        }

        std::cout &lt;&lt; ' ' &lt;&lt; std::setfill(' ')
            &lt;&lt; std::setw(10) &lt;&lt; std::left &lt;&lt; i-&gt;first
            &lt;&lt; std::setw(6) &lt;&lt; std::internal &lt;&lt; i-&gt;second &lt;&lt; '\n';
    }
}

int main(int argc, char *argv[])
{
    Words words;

    for (int i = 1; i &lt; argc; ++i)
    {
        if (!loadFromFile(argv[i], words))
        {
            std::cerr &lt;&lt; "Can't open the file " &lt;&lt; argv[i] &lt;&lt; '\n';
        }
    }

    showResult(words.begin(), words.end());
}
Overall, this looks pretty nice. There are few minor things that can be improved though, about this part:


int x = 0;

for (const auto&amp; i : words)
{
    if (x++ == 0)
    {
        std::cout &lt;&lt; "\nThe most repeated element is: " &lt;&lt; i-&gt;first &lt;&lt; "\n\n";

        std::cout &lt;&lt; " Word\tRepeated Times";

        std::cout &lt;&lt; '\n' &lt;&lt; std::setfill('-') &lt;&lt; std::setw(23) &lt;&lt; '\n';
    }

    // ...
}



i is customary for loop variables that are simple counters.
In this case it is a word (well, sort of), 
so it would be better to name it as such.

The variable x is a bit confusing:


its name tells nothing of its purpose
it's important for the first iteration of the loop
... but it keeps counting during all iterations


It would be clearer and better this way:

bool first = true;

for (const auto&amp; word : words)
{
    if (first)
    {
        std::cout &lt;&lt; "\nThe most repeated element is: " &lt;&lt; word-&gt;first &lt;&lt; "\n\n";

        std::cout &lt;&lt; " Word\tRepeated Times";

        std::cout &lt;&lt; '\n' &lt;&lt; std::setfill('-') &lt;&lt; std::setw(23) &lt;&lt; '\n';

        first = false;
    }

    // ...
}