Hi!
I'm trying to count the number of occurrences of each word in a text file. But program put in the file the first symbol of inputed word only (line 34) and don't enter in the for-statement (line 51). What should I serach for in my code in order to find the problem?
Thanks in advance.

#include <fstream.h>
#include <iostream.h>
#include <map.h>
#include <string>
#include <iterator>
#include <cstdlib>
#include <iomanip>
#include <conio.h>

typedef std::map<std::string, int> StrIntMap; // map for counting

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

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

using namespace std;

int main ()
{
  char str [80];

  ofstream out("test.dat");
  if(!out) {
        cout << "Cannot open file.\n";
        return 1;
}

  do {
        cout << "Enter a word (BL to quit):\n";
        cin >> str;
        out << str;
        } while(*str != '\n'); // if empty str inputed -> stop do-while
  out.close();

  ifstream in("test.dat");
    if(!in) {
        cout << "Cannot find file.\n";
        return 1;
}


  StrIntMap w;
  countWords(in, w);

    for (StrIntMap::iterator p = w.begin( ); p != w.end( ); ++p)
    {   std::cout << "\nPress any key to close";
        std::cout << setw(30) << left  << p->first  << " occurred "
                  << setw(10)  << right << p->second << " times.\n";
    }

  std::cout << "\nPress any key to close";

getch();
return 0;
}

Thank you so much.
Could you explain how to make as a sign of completion of input is null string?

The first thing I notice is that the following accomplishes nothing (unless by "nothing" you wanted an infinite loop):

} while(*str != '\n'); // if empty str inputed -> stop do-while

You're using the >> operator to populate str, and that operator is delimited by whitespace. In other words, '\n' (which constitutes whitespace) will never be stored in str.

While we're here, I see that you're comfortable using C++ string objects in your code. Why use a char array for str rather than a C++ string?

Thank you. This is working code of this problem but it is necessary to set as a sign of completion of input is null string (instead symbol "BL" - line 34). How to realize input closing by the null string?

#include <fstream.h>
#include <iostream.h>
#include <map.h>
#include <string>
#include <iterator>
#include <cstdlib>
#include <iomanip>
#include <conio.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 ()
{
  string str;

  ofstream out("test.dat");
  if(!out) {
        cout << "Cannot open file.\n";
        return 1;
}
  cout << "Enter a word: \n";
  while ( ( cin >> str ) && str != "BL" )
  { out << str << " ";
    cout << "Enter the next word (BL to quit):\n";
    }
  out.close();

  ifstream in("test.dat");
    if(!in) {
        cout << "Cannot find file.\n";
        return 1;
}


  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";
    }

  std::cout << "\nPress any key to close";

getch();
return 0;
}
Member Avatar for iamthwee

I just remove line 36. Searching for 'BL' is just the same as searching for null string -I don't think you can make a std::string a null string anyway, it makes no difference. Get rid of the .h in the includes as they are not valid. Get rid off conio.h as well, it is non standard, cin.get() will suffice here.

#include <fstream>
#include <iostream>
#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 ()
{
  string str;

  ofstream out("test.dat");
  if(!out) {
        cout << "Cannot open file.\n";
        return 1;
}
  cout << "Enter a word BL to quit: \n";
  while ( ( cin >> str ) && str != "BL" )
  { out << str << " ";

    }

  out.close();

  ifstream in("test.dat");
    if(!in) {
        cout << "Cannot find file.\n";
        return 1;
}


  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";
    }

  std::cout << "\nPress any key to close";
std::cin.get();
//getch();
return 0;
}

Sample output

cr@cr-Aspire-V5-122P:~/Documents/cpp$ g++ -Wall -pedantic test.cc
cr@cr-Aspire-V5-122P:~/Documents/cpp$ ./a.out
Enter a word BL to quit: 
all work and no play makes jack a   dull boy
all work    and no play makes jack a dull boy
BL
a                    occurred     2 times.
all                  occurred     2 times.
and                  occurred     2 times.
boy                  occurred     2 times.
dull                 occurred     2 times.
jack                 occurred     2 times.
makes                occurred     2 times.
no                   occurred     2 times.
play                 occurred     2 times.
work                 occurred     2 times.
Member Avatar for iamthwee

I would also change line 33. to read enter a sentence as it makes more sense.

OK, but it is necessary to close input by pressing "Enter" instead of typing symbols "BL". How to realize this?

Member Avatar for iamthwee

You can use getline instead.

E.g.

cout << "Enter a sentence: \n";
  // while ( ( cin >> str ) && str != "BL" )
  // { out << str << " ";

  //   }
  std::getline(cin, str);
  out << str;

Hey Iamthwee, first off thank you for your insight, your explanation makes it more clear to me.
Thanks again!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.