Filling array with words from text file and finding similar ones and sorting them out

Hello everyone,

First of all sorry for my poor English skills and I'm new to C++ too so don't judge me too much and I would appreciate if someone could try to help me. Basically I have a .txt file and I need to fill an array with the words from the file. Once I do that I need to find the words which start and end with same letter and sort them all out. I know how to sort it out, but I need help with the other two mentioned earlier. So what I've managed to do so far is to print out the content of a file word by word assuming that they're places in an array (in my case word[n]) array. But as soon as try to write let's say cout << word[somenumber]; it doesn't give me anything and same if I try with "for" loop, where could the problem be? Because it prints out everything fine at first in the "for" loop. Maybe there is a smarter and more elegant way to do this?

Thank You for your time.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
      i = 0;
    string word[MAX];
    vector<string> Words;
			ifstream fv;
			fv.open("data.txt");
			if(fv.fail()) cout<<"File can not be found";
			else{
                    for(i=0;i<500;i++)
                    {

				while(fv >> word[i])
  {
    cout << word[i] << endl; // <--- This does work!
    Words.push_back(word[i]);
  }
                    }
}
for(i=0;i<500;i++)
{
    cout << word[i] ; // <--- This doesn't work!
}

}
Hello Mykel,

Not seeing the rest of the code some of the variables are out of context. Also the text file or a portion of it would be helpful. At least we would all be using the same information.

Just looking at the code I would consider removing the first for loop and letting the while loop control the input. As it is when the while loop has nothing left to read the for loop will continue using whatever was in the last read.

In the second for loop did you want to pront the array of strings or the vector of strings?

Personally I would stay with the vector.

It would help if your spacing, indentation and {}s are done better along with some blank lines.

As a suggestion:
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
i = 0;  // <--- Unless defined earlier it needs a type.
string word[MAX];
vector<string> Words;
ifstream fv;
fv.open("data.txt");

if (fv.fail())
	cout << "File can not be found";
else
{
	for (i = 0; i < 500; i++)
	{

		while (fv >> word[i])
		{
			cout << word[i] << endl; // <--- This does work!
			Words.push_back(word[i]);
		}
	}
}
for (i = 0; i < 500; i++)
{
	cout << word[i]; // <--- This doesn't work!
}

}  // <--- Do not know what this belongs to? 


Hope that helps,

Andy
your code, indented
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
i = 0;
string word[MAX]; //¿why do you have both an array and a vector?
vector<string> Words;
ifstream fv;
fv.open("data.txt");
if(fv.fail())
	cout << "File can not be found";
else {
	for(i = 0; i < 500; i++) { //magic 500
		while(fv >> word[i]) { //notice the nested loop, you always read on word[0]
			cout << word[i] << endl;
			Words.push_back(word[i]);
		}
	}
}
for(i = 0; i < 500; i++) { //all your strings are empty at this point
	cout << word[i];
}
}
word[1--499] are empty as you never put anything on them
word[0] is empty because the last reading operation failed on it.
I've fixed the code (the problem was in the first "for" loop which is not even needet) and now I have my array filled with words in each of it's elements. Now my question would be the second thing I mentioned before: How to find words that starts and end with same letter? In my logic it will have to do something with the lenght of the word, then we could check lets say if the first element(letter) equals to the last by substracting word letters that there would be left only one - the last one, but I don't have and idea how to approach that.
Last edited on
Hello Mykel,

I would start with a function that takes two vectors. The first is the one you filled from the input file and the second is to hold the words that you fine.

You will most likely have to check the word for any punctuation that you do not need. With the file I used some words ended with a period that will need to be removed. Look at: http://www.cplusplus.com/reference/string/string/ the first function that you will need to remove the period is "pop_back" which removes the last character in the string. Then check the first and last characters to see if they match. If so put this word in the second vector.

Quick thoughts for now. I may come up with something different later.

Hope that helps,

Andy
to get the first character http://www.cplusplus.com/reference/string/string/front/
to get the last character http://www.cplusplus.com/reference/string/string/back/
make sure to handle correctly empty strings and strings with only one element.
Hello Mykel,

@ne555 Thanks for the tips. I liked the front and back.

To start I added these header files:
1
2
3
#include <cctype>
#include <chrono>
#include <thread> 


The last are used here:
1
2
3
4
5
6
	if (fv.fail())  // <--- Could also be written as (!fv)
	{
		std::cout << "File can not be found";
		std::this_thread::sleep_for(std::chrono::seconds(3));  // Requires header files "chrono" and "thread"
		exit(1);  // <--- Because there is no reason to continue.
	}

This way there is a pause to allow the user to read the message before the program ends and the console window closes.

To give you an idea I created a function.

I start with defining two variables "std::string word;" and "std::size_t len{};"
This way I take an element of the vector and put it into "word" to work with.

For "len" I set this to "word.size() - 1" to have the last element of the string
and as ne555 suggested to test if it is worth continuing or moving to the next
word.

While working on the function I realized that you will need to change the word
to either lower or upper case. Otherwise a comparison between different cases
would not work.

After this I check for punctuation and removed anything at the end. At this
point you could check the string for anything else you do not want like numbers
or spaces and remove them if needed.

If "word.front() == word.back()" I put this in the second vector for later
processing.

There are two functions that you will need to write. One to check each word and one to change to a single case.

Work something up and we can go from there.

Hope that helps,

Andy
Topic archived. No new replies allowed.