Reputation: 45
I am a beginner in C++ and I am able to add words dynamically from a file to a vector array, but I want to take each word and find out how many times that word occurs in the file and print the word only once and list the line number of each time it occurs. I am not sure where to go from my vector of words. Is there a way to compare each string element? Here is my source code:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>#include
using namespace std;
int main() {
ifstream inFile, testStream;
ofstream outFile;
vector<string> words;
string temp, choice, inFileName, outFileName, word, trash;
int idx = 0, lineCount = 0;
bool outputOpened = false;
stringstream wordStream;
for (;;) {
cout << "Options: "<< endl << "1. Index" << endl << "2. Quit" << endl
<< "Please enter an option: ";
getline(cin, temp);
choice.resize(temp.length());
transform(temp.begin(), temp.end(), choice.begin(), ::toupper);
if (choice.compare("INDEX") == 0 || choice.compare("1") == 0) {
do {
inFileName.clear();
cout << "Index Program" << endl
<< "==============" << endl << endl;
cout << "Input file name: ";
getline(cin, inFileName);
inFile.open(inFileName.c_str());
if(inFile.fail()) {
cout << "Can't open file" << endl;
if(inFile.bad()) {
cout << "Bad" << endl;
}
inFile.clear();
}
}
while (!inFile.is_open());
do {
cout << "Output file name: ";
getline( cin, outFileName);
testStream.clear();
testStream.open(outFileName.c_str());
if(testStream.good()) {
cout << "That file already exists, try again" << endl;
testStream.clear();
testStream.close();
}
else {
testStream.clear();
testStream.close();
outFile.open(outFileName.c_str());
if (outFile.good()) {
outputOpened = true;
}
}
}
while (!outputOpened);
while (inFile.peek() != EOF) {
getline(inFile,word, ' ');
lineCount++;
words.push_back(word); // now the vector 'words' contains all words in the file
}
for (idx = 0; idx < words.size(); idx++) {
outFile << words[idx] << endl;
}
}
else if (choice.compare("QUIT") == 0 || choice.compare("2") == 0) {
return 0;
}
else {
cout << temp << " is an unrecognized option, please try again" << endl;
}
}
return 0;
}
Upvotes: 0
Views: 4436
Reputation: 10820
For what you're trying to achieve there is a better way: std::map. You use a map (just like in the example from the link) and each time you want to add a new element you first search if it exists. If it does not then you initialize it with 1.
yourMap[yourString]=1;
If the string already exists then you increment that counter:
yourMap[yourString]=1+yourMap[yourString];
Upvotes: 1
Reputation: 33655
Here are some hints:
vector
, consider using a map
- this will allow you to associate a count with a given wordOn your specific problem. std::string
has operator==
implemented, so you can simply compare for equality, e.g.
std::string f("foo");
std::string b("bar");
if (f == b)
std::cout << "foobar" << std::endl;
Some other hints:
Use the stream operations to read a word at a time, rather than peek()
for EOF, something like:
// assume fin is a file input stream
std::string word;
while(fin >> word)
{
if (!word.empty())
{
// do stuff with word...
}
}
Upvotes: 2