Issue with program that reads a .txt file

I am trying to create a program that reads a .txt file, displays it, counts unique words and displays unique words next to how many times used. So far I have the number of total unique words and the unique words used. I am a little stuck on how to count the number of times each word was used rather than just the overall total of unique words. How would I display the text from the file as well? My current print statement prints the word the number of times it appears and I want to change it to something like this: " as: 6 " etc...in alphabetical order. Any suggestions or help would be appreciated.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <algorithm>
#include <cctype>
#include <string>
#include <set>
#include <fstream>
#include <iterator>
#include <iostream>
using namespace std;

string ask(string msg) {
string ans;
cout << msg;
getline(cin, ans);
return ans;
}

int main() {
ifstream fin( ask("Enter file name: ").c_str()); //open an input stream on 
the given file
if( fin.fail() ) {
    cerr << "An error occurred trying to open the file!\n";
    return 1;
}

istream_iterator<string> it{fin};
set<std::string> uniques;
transform(it, {}, inserter(uniques, uniques.begin()), 
    [](string str) // make it lower case, so case doesn't matter anymore
    {
        transform(str.begin(), str.end(), str.begin(), ::tolower);
        return str; 
    });

cout << "" << endl;
cout << "There are " << uniques.size() << " unique words in the above text." << endl;
cout << "----------------------------------------------------------------" << endl;
cout << " " << endl;    

// display the unique elements
for(auto&& elem: uniques)
    for (int i=0; i < uniques.size(); i++)
        cout << " " << elem << endl;      


// display the size:
cout << std::endl << uniques.size();
return 0;

}
You could use a map<string,int> rather than a set. Test for existence at insert, incrementing the int where necessary.

Alternatively, you could put them in a vector<string>, sort it, and do the counting as a final pass.
So I completely revamped my program using map and fixed some other problems. I just can't print out the text file. Above the sorted words and how many times they appear, I want to display the text from the file. How would I do that? I tried several thing but it either does nothing or screws up the rest of the code saying there are 0 unique words. And lastly how would Print out the results so they are more ... table -ish...
Something like this:
Word: [equal spaces] Count:
ask [equal spaces] 5
anger [equal spaces] 3



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

#include <iterator>
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <cctype>

using namespace std;

string getNextToken(istream &in)
{
    char c;
    string ans="";
    c=in.get();
    while(!isalpha(c) && !in.eof())//cleaning non letter charachters
    {
        c=in.get();
    }
    while(isalpha(c))
    {
        ans.push_back(tolower(c));
        c=in.get();
    }
    return ans;
}

string ask(string msg) {
	string ans;
	cout << msg;
	getline(cin, ans);
	return ans;
}


int main() {

        
	map<string,int> words;
	ifstream fin( ask("Enter file name: ").c_str() ); //open an input stream on the given file
	if( fin.fail() ) {
		cerr << "An error occurred trying to open a stream to the file!\n";
		return 1;
	}

    string s;
    string empty ="";
    while((s=getNextToken(fin))!=empty )
            ++words[s];

	while(fin.good()) 
   		cout << (char)fin.get();  
   		
	cout << "" << endl;
	cout << "There are " << words.size() << " unique words in the above text." << endl;
	cout << "----------------------------------------------------------------" << endl;
	cout << " " << endl; 
	
    for(map<string,int>::iterator iter = words.begin(); iter!=words.end(); ++iter)
        cout<<iter->first<<' '<<iter->second<<endl;
        
        
        
}
Last edited on
If you just want to print the original contents of a file you can use the printFile function below.

If you want to prettify the output table, use <iomanip> - look at setw() etc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <fstream>
using namespace std;

void printFile( string filename )
{
   char c;
   ifstream in( filename.c_str() );              // .c_str() not needed for c++11
   while ( in.get( c ) ) cout.put( c );
   in.close();
}

int main()
{
   string s;
   cout << "Enter name of file: ";   cin >> s;
   cout << "**** File contents ****\n";
   printFile( s );
   cout << "**** End of file contents ****\n";
}
Topic archived. No new replies allowed.