Need help with my program

Full disclosure: This is an assignment for my CS class. I'm not asking for a full answer, I just need help on trying to see and understand the program. My assignment needs me to find the word count, create a search function, and find the 5 most and least used words in a text file. I have gotten the word counter part of the function, but my search function isn't finding anything. I also can't get the most or least repeated word function working as well. I have been following most of the startegies he posted for the assignment, but I haven't gotten anywhere. I have to do this all while not using the vector class or using any c++ 11 containers. Here is my code so far:

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
  int main(){
#include <iostream>
#include <string>
#include <cctype>
#include <fstream>
using namespace std;

const int ARRAY_SIZE = 1000;
const int NOT_FOUND = -1;

//Prototypes Start//
void loadData();
string convertCase(string word);
int search(string words[], string searchWord, int totalWords);
int findIndexofMost(int counts[], int totalWords);
//Prototypes End//
int main() {
	loadData();
	
	system("pause");
	return 0;
}

void loadData() {
	string filename, searchWord;
	int numOfWords = 0, indexCount = 0, totalWords = 0, index = 0, most = 0;
	int counts[ARRAY_SIZE] = { 0 };
	string words[ARRAY_SIZE] = { "" };
	ifstream inFile;
	cout << "Enter a text file: ";
	cin >> filename;
	words[indexCount] = filename;
	inFile.open(words[indexCount]);
	while (inFile >> words[indexCount]) {
		counts[numOfWords]++;
		words[indexCount] = convertCase(words[indexCount]);
		cout << words[indexCount];
		if (inFile.get() == 32)
			cout << " ";
		else
			cout << endl;
	}
	cout << endl << "total words: " << counts[numOfWords] << endl;
	//------^^^^^^^^^^^^From here up is good^^^^^^^^^^^^^^^^^^^^^-----------	
        cout << "Search a word: ";
	cin >> searchWord;
	getline(inFile, searchWord);
	inFile >> searchWord;
	index = search(words, searchWord, totalWords);
	counts[index]++;
	if (index == NOT_FOUND) {
		cout << "\"" << searchWord << "\"" << " was not found." << endl;
	}
	else {
		cout << endl << "the word " << "\"" << searchWord << "\"" << " is found on at index " << index;

		most = findIndexofMost(counts, totalWords);
		cout << most;
	}

}



string convertCase(string word) {
	for (int i = 0; i < word.length(); i++) {
		word[i] = tolower(word[i]);
	}
	return word;
}
int search(string words[], string searchWord, int totalWords) {
	int index = NOT_FOUND;
	for (int i = 0; i < totalWords; i++) {
		if (words[i] == searchWord) {
			index = i;
			break;
		}
	}
	return index;
}
int findIndexofMost(int counts[], int totalWords) {
	int most;
	most = counts[0];
	for (int i = 0; i < totalWords; i++) {
		if (counts[i] > most) {
			most = counts[i];
		}
	}
	return most;
}

return 0;
}
One problem is that you rea all the words into words[0] because you dont increment indexCount.
What is the point of storing the filename in words ?
Hello leon9696,

My observations. The "loadData" function should do one thing load data. The search is better suited in the "search" function. The variables you define on lines 26 - 28 should be defined in main and passed to the function. If you are not aware of it, when the function ends, so do the variables. There is no way to use them in other functions.

It is a moot point, but lines 47 and 48 will never work because "eof" has been reached and the "eof" state bit is set for the stream so each read will fail. Not only would you have to reset the state bits you would also have to move the file pointer back to the beginning of the file. But you should be using the words array not reading the file.

For the "loadData" function most variables should be passed as a reference. The arrays do not have to be passed by reference.

I would start first by reading the file and loading the array and make sure that works first before proceeding to the other functions.

Hope that helps,

Andy
Thanks for your response Handy Andy, I got rid of loadData and put the program into main. I also got rid of lines 47-48. I can't use the search function, because my teacher said that I have to do it myself. Also, how do I go about loading the array with the file?
Hey Thomas1965, the reason I stored filename into words was because I thought that would load the file into the array function.
The easiest way would be to use a map but I am afraid you are not allowed.
Next - bit more complicated - option would be to use an array of struct consisting of the word and its count but you are probably not allowed.
Next option is to use two arrays. One of type string to store the words and one of type int to store the count.
When you read the file word by word you need to convert it to lowercase and see if it is in the array already. If it is you update the corresponding count, if not you add it to the array and set it's count to 1.
To find the 5 most and least used words the easiest solution would be to sort the arrays - if you are allowed.
So using line 32 didn't load my file into the array? Should the update of the count be an increment like counts[totalWords]++?
Last edited on
So using line 32 didn't load my file into the array?

No uou have to read file by yourself.
To read the words from the file you need to use an ifsteam.
http://www.cplusplus.com/doc/tutorial/files/

Should the update of the count be an increment like counts[totalWords]++

Yes but you need to find the right index of the array first. For that you need a simple linear search.
Do it one step at a time. I think best is to get aquainted with the files first and forget the project for a little while.
Hello leon9696,

There is nothing wrong with keeping the load data function. Or do it all in main. Either way works. This is my idea on the "loadData" function:

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
void loadData(int& numOfWords,
	int& indexCount,
	int& totalWords,
	string words[],
	int counts[])
{
	string filename{ "Words File.txt" }, word{ "" };
	//int numOfWords = 0, indexCount = 0, totalWords = 0, index = 0, most = 0;  // <--- Moved to main.

	ifstream inFile;

	cout << "\n Enter a text file: ";
	std::cout << filename << std::endl;
	//cin >> filename;

	inFile.open(filename);

	//  <--- My check to see if the file is open.
	if (inFile.is_open())
	{
		// Comment these lines out when satisified.
		std::cout << "\n File \"" << filename << "\" is open" << std::endl;
		std::this_thread::sleep_for(std::chrono::seconds(2));  // <--- Needs header files "chrono" and "thred"
	}
	else
	{
		std::cout << "\n File " << filename << " did not open" << std::endl;
		std::this_thread::sleep_for(std::chrono::seconds(3));
		exit(1);
	}

	// <--- Code to read the file.
	while (inFile >> word)
	{
		size_t found{ 0 };

		// <--- These next lines used to stri[ any punctuation from the word. 
		found = word.find_first_of(",.?!");

		if (found != std::string::npos && found == word.size() - 1)  // <--- The && to make sure the punctuation is at the end. The && part may not be needed.
		{
			word.erase(found, 1);  // <--- Builtin string function.
		}

		words[totalWords++] = convertCase(word);  // <--- Stores word in the array. increments total word count.
	}

	cout << endl << " total words: " << totalWords << endl;
}


Some of the variables I did not use because I have not figured out what to do with them.

I do not see anything wrong with your search function except the way you did it. It does not use any built in means of searching and one way or another you will have to search the array at some point.

The end of the while loop is one way to add the words read from the file and store them int the array.

Hope that helps,

Andy
Topic archived. No new replies allowed.