Recursively transfer strings from istream into array - C++
Recursively transfer strings from istream into array - C++
I am trying to copy in strings from a .txt
file (every word is on a new line) into an array. The main routine would look like this.
.txt
const int MAXDICTWORDS = 5000;
int main()
{
string dict[MAXDICTWORDS];
ifstream dictfile; // file containing the list of words
dictfile.open("words.txt");
if (!dictfile) {
cout << "File not found!" << endl;
return (1);
}
int nwords = dicReader(dictfile, dict);
// dict should now hold array of words from words.txt
// nwords will be the amount of words in the array
}
This is my current implementation of dicReader
. dict
will always be empty when passed to this function. I am practicing with recursion, so no while
or for
loops can be used. Any ideas on what I am missing?
dicReader
dict
while
for
int dicReader(istream &dictfile, string dict)
{
int count = 0; // know this is wrong, recursive call will always reset count to 0
string item;
if (!dictfile.eof())
{
dictfile >> item;
dict[0] = item;
dicReader(dictfile, dict + 1); // is this the correct recursive call?
count++;
}
return count;
}
dicReader
dictionaryReader
Are you sure you want to do it recursively?
– Martin York
yesterday
2 Answers
2
You are not using count
correctly.
count
You need to keep accumulating the value in the recursive calls.
Also, if (!dictfile.eof())
is wrong. See Why is iostream::eof inside a loop condition considered wrong? for details.
if (!dictfile.eof())
The function can be simplified to:
int dictionaryReader(istream &dictfile, string dict)
{
if (dictfile >> dict[0])
{
return (1 + dictionaryReader(dictfile, dict + 1));
}
return 0;
}
Tail recursion might be worth mentioning.
– john
yesterday
@john, that might be more than what the OP can digest.
– R Sahu
yesterday
OK well I'll have a go.
– john
yesterday
Thanks @john! Please do. @R Sahu - I am assuming the conditional will always cast to true if there are words left in the istream. Is that correct? Also, does the recursive call's second parameter of dict+1 ensure that we cannot return a value of MAXDICTWORDS? i.e. if we don't copy in a string from dictfile because dict[0] doesn't point anywhere, we return 0 and end our recursive call?
– aelarabi
yesterday
@aelarabi, the expression will evaluate to
true
as long as the read is successful. it does not say anything about what's left in the stream. No to the second question. If you need to make sure that you don't read more than what the original can array can hold, you'll have to add more bookkeeping data.– R Sahu
yesterday
true
R Sahu has given you a complete answer, but there is an alternative way to formulate the recursive function. This alternative has the count
variable as a parameter to the function. Like this
count
int dictionaryReader(istream &dictfile, string dict, int count)
{
if (dictfile >> dict[0])
{
return dictionaryReader(dictfile, dict + 1, count + 1);
}
return count;
}
When the function is initially called you supply a value of zero for count
.
count
int nwords = dictionaryReader(dictfile, dict, 0);
In this implementation dictionaryReader calls itself and returns the resulting value directly. This is called tail recursion. In the alternative implementation dictionaryReader calls itself and then adds one to the result, so it isn't tail recursive.
The advantage of tail recursion is that it is trivially converted into a while loop (the while loop you were told to avoid). Some compilers perform this conversion for you as an optimisation. So you write a tail recursive function but end up with the same code as if you had written a while loop.
That's definitely better as a second answer. It will be helpful to someone, I am sure.
– R Sahu
yesterday
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
It's not the correct call, if only because the function is called
dicReader
notdictionaryReader
. A minor point but it is a good idea to avoid confusion by posting the genuine code, not untested code that might or might not illustrate your real problem.– john
yesterday