learning STL, no error, but doesn't work

So I'm working on this assignment for finding anagrams, and I have it at that, code complete ready to run and change stuff so it runs right phase.. debugging.
It seems to be acting up at my keyHolder function and in for_each. I tried stepping through it in the debugger, but I can't step into my own function for keyHolder, it goes into xstring lala land.. Also, I failed at functors, but that's another topic for now. Anyone have any ideas on why this is failing at that point. line 75 - 77.

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
#include <iostream>
#include <algorithm>
#include <vector>
#include <fstream>
#include <iterator>
#include <string>

using namespace std;

/*
 * Need to remember the word to compare with
 */
string keyHolder(string kWord)
{
	static int i = 0;
	static string key;
	if (i == 0) {
	key = kWord;
	i = 1;
	return "";
	} 
	return key;
}

void display(string anagram)
{
	if (anagram != keyHolder("dummy"))
		cout << anagram << endl;
}

/*
 * Might require C++ 11 for is_permutation function.
 */
void anaFinder(string cWord)
{
	string keyWord = keyHolder("dummy");
	string compWord = cWord;
	static vector<string> matches;

	if (is_permutation(keyWord.begin(), keyWord.end(), cWord.begin() ) ){
		matches.push_back(cWord);
	}
	if (!matches.empty()) {
		cout << "Anagrams: " << endl;
	    for_each(matches.begin(), matches.end(), display);
	} else {
		cout << "No anagrams exist." << endl;
	}
}

int main()
{

	typedef istream_iterator<string> isIterator;
	string filename;
	string keyWord;

	cout << "Enter a Filemame: ";
	cin >> filename;
	cout << endl;

  
	ifstream file(filename);
	vector<string> dictionary;

	
	copy(isIterator(file), isIterator(), back_inserter(dictionary));

	file.close();

	cout << "Enter a word: ";
	cin >> keyWord;
	cout << endl;

	keyHolder(keyWord);

	for_each (dictionary.begin(), dictionary.end(), anaFinder);
	cout << endl;

	return 0;
}


Thanks!
Chris
Last edited on
i couldn't spot any error but of course it must exist.

I suggest you try out the good old method of cout at every step to see what the program is doing correctly and where it is giving unexpected results.

For instance check that the dictionary vector is made correctly and within each function you output the parameters to see when and why the program is malfunctioning.
What do you mean by "acting up"? Do you get an error message? Does it not work like you expected? Please explain.
This
 
ifstream file(filename);

should be
 
ifstream file(filename.c_str());


Don't call close() on a stream. Let it go out of scope and allow the destructor to the right thing.

Declare variables where they're used.

Pass read only objects by const reference rather than value.

Is there a reason you've used
 
using namespace std 


Anyway, without compiling your code, it's not obvious what's wrong with it.
for_each is called on each object in your dictionary, so each call starts the function over again, meaning the matches vector, and other stack variables are recreated on each object.

Try using std::copy_if instead.

http://www.cplusplus.com/reference/algorithm/copy_if/
Use std::map<> or std::unordered_map<> for the look up.

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
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <cctype>
#include <algorithm>

std::string make_key( std::string str )
{
    // remove non-alphabets
    static const auto is_not_alpha = [] ( char c ) { return !std::isalpha(c) ; } ;
    str.erase( std::remove_if( str.begin(), str.end(), is_not_alpha ), str.end() ) ;

    // convert to lower case
    for( char& c : str ) c = std::tolower(c) ;

    // and sort
    std::sort( str.begin(), str.end() ) ;

    return str ;
}

using anagram_map = std::map< std::string, std::vector<std::string> > ;

anagram_map make_anagram_map( std::istream& stm )
{
    anagram_map ana_map ;

    std::string word ;
    while( stm >> word ) ana_map[ make_key(word) ].push_back(word) ;

    return ana_map ;
}

void look_up( const std::string& word, const anagram_map& ana_map )
{
    auto iter = ana_map.find( make_key(word) ) ;
    if( iter != ana_map.end() )
    {
        std::cout << "anagrams of '" << word << "':\n" ;
        for( const auto& str : iter->second ) std::cout << "    " << str << '\n' ;
    }
    else std::cout << "no anagrams of '" << word << "' were found\n" ;
}

#include <sstream>

int main()
{
    std::istringstream stm( "Petal Maple Teal leapt!! Lepta tale Pleat ample LATE? Plate" ) ;
    const anagram_map ana_map = make_anagram_map(stm) ;

    look_up( "petal", ana_map ) ;
    look_up( "late", ana_map ) ;
    look_up( "quick", ana_map ) ;
}

http://ideone.com/duNMco
@kbw

Isn't ifstream file(filename); valid C++11 ??

(the OP mentions C++11 on line 32...)

There's a new overload:

1
2
3
4
void open (const char* filename,
           ios_base::openmode mode = ios_base::in | ios_base::out);
void open (const string& filename,
           ios_base::openmode mode = ios_base::in | ios_base::out);


http://www.cplusplus.com/reference/fstream/fstream/open/

Andy
Isn't ifstream file(filename); valid C++11 ??
I guess so. My real fault was trying to second guess some mysterious and unspecified problem.
Wow, thanks everyone. I'll work with these suggestions and see what happens. Thanks again.
Topic archived. No new replies allowed.