Hello funs2code!
I have the following problem. I need to count the number of occurrences of a concrete word in a text file. I've tried to count the number of occurrences of each word at first.
The following code has no errors but it isn't working! When I type in a command line "project1.exe test.dat cat dog cat dog" the empty string is showed. I've cheked if-statements -> right working. Then I've made a conclusion that problem is in for-statement (with iterators). Can anyone explain me, guys?

#include <iostream.h>
#include <fstream.h>
#include <map.h>
#include <string.h>
#include <iterator.h>

typedef std::map<std::string, int> StrIntMap;

void countWords(std::istream& in, StrIntMap& words) {
std::string s;

  while (in >> s) {
++words[s];
  }

}

using namespace std;

int main(int argc, char** argv) {

    if (argc < 2) {
                printf("\nNot correct input");
        return(EXIT_FAILURE);
                }

ifstream in(argv[1]);
    if (!in) {
                printf("\nFile ");
                printf(argv[1]);
                printf(" is not found");
        exit(EXIT_FAILURE);
                }
StrIntMap w;
countWords(in, w);

    for (StrIntMap::iterator p = w.begin( );
    p != w.end( ); ++p) {
        std::cout << p->first << " occurred "
        << p->second << " times.\n";
    }

}

I'm making the assumption here that your actual command line is "project1.exe test.dat", and that project1.exe is the executable made from the code above, and that the file "test.dat" contains the text "cat dog cat dog".

Your code (whilst using a compiler from two decades ago - iostream.h and other such C++ headers with ".h" on the end vanished from C++ in 1998) is fine.

That said, I must confess I don't know what the standard says an int in a map will be initialised to, and possibly it won't be initialised to zero by default, so maybe you should be doing that yourself - maybe someone else here can fill in this gap in my knowledge.

The output is:

cat occurred 2 times.
dog occurred 2 times.

If you don't see that, the problem isn't in your code (although with a compiler from two decades ago, maybe it's doing something differently or wrong).

Edited 2 Years Ago by Moschops

I have no idea either. Quick search though the standard:

According to ISO/IEC 14882:2011 section 24.4.4.2:

23.4.4.2 map constructors, copy, and assignment [map.cons]
    explicit map(const Compare& comp = Compare(),
                 const Allocator& = Allocator());
    1
    Effects: Constructs an empty map using the specified comparison object and allocator.
    2
    Complexity: Constant.

Ah. I think your on to something.

Hi @Moschops. Your assumption is right. But I use C++ Builder 6.0 and it recognize <map.h> and <map> simultaneously. Maybe error in "w" declaration (row 35).

Add some loglines to your code. Here are some good questions to get answers to by adding loglines.

What is the size of the map on creation?
What is the size of the map after each word is added?
What is the value of words[s] each time you increment it?
What is the complete contents of the map after countWords returns?

You could also answer these questions by using a debugger and breaking at the relevant points in the code.

This is working code:

#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <iterator>
#include <cstdlib>
#include <iomanip>

typedef std::map<std::string, int> StrIntMap;

void countWords(std::istream& in, StrIntMap& words)
{
    std::string s;

    while (in >> s)
    {
        ++words[s];
    }
}

using namespace std;

int main(int argc, char** argv)
{
    if (argc < 2)
    {
        printf("\nNot correct input");
        return EXIT_FAILURE;
    }

    ifstream in(argv[1]);
    if (!in)
    {
        printf("\nFile ");
        printf(argv[1]);
        printf(" is not found");
        exit(EXIT_FAILURE);
    }

    StrIntMap w;
    countWords(in, w);

    for (StrIntMap::iterator p = w.begin( ); p != w.end( ); ++p)
    {
        std::cout << setw(20) << left  << p->first  << " occurred "
                  << setw(5)  << right << p->second << " times.\n";
    }

}
This question has already been answered. Start a new discussion instead.