1

Hey. I'm trying to read strings into an array from a file that contains a list of words. This is so that I can check to see if strings are a real word by seing is they exist inside my array. I have everything working except the compare. My binary search even passes by the word in question. When it compares the two words which are exactly the same, it still returns false. I think the problem is probably in the way I am pulling the words in because the string.compare() function works fine normally. Here is that code. I would love some help. Thanks.

  ifstream dictFile;
  dictFile.open("dictionary.txt");
  if (!dictFile) // testing if file open
    {
      cout << "Error opening dictionary file" << endl;
    }
  int index = 0; // dictionary must progress start at line 1
  while(!dictFile.eof())
    {
      getline(dictFile,dictionary[index]);
      index++;
    }
  dictFile.close();

Is there anything just plain wrong about how I am doing this?

EDIT Here is the comparison code as well

bool database::is_word(string word)
{
  int ii;
  int comp;
  int min = 0;
  int max = dictSize;
  // this will go into the dictionary and look for the word
  // it uses a binary search pattern
while (min<=max)
    {
      ii = (min+max)/2;
      comp = word.compare(dictionary[ii]);
      cout <<dictionary[ii];
      if (comp==0)
    {
      cout << word<< " is a word!" << endl;
      return 1;
    }
      else if (comp < 0)
    {
      max = ii-1;
    }
      else
    {
      min = ii+1;
      }
      }
 cout << word << " is NOT a word!" << endl;
  return 0;
}
4
  • Is getline retrieving the word as well as the \n (return) at the end of the line? If so, the compare could think that the words are different because it would loook like "word" != "word\n". Just a thought. Commented Apr 26, 2011 at 16:34
  • @Tyler getline() removes the newline. Commented Apr 26, 2011 at 16:37
  • Can you add in the code that you use for string comparison? It's probably an issue with whatever function you're calling for comparison rather than a file read problem itself. Commented Apr 26, 2011 at 16:45
  • Hmm... how are you calling is_word and are you sure that your dictSize variable is valid? I just wrote some quick test code and it works perfectly for me. Commented Apr 26, 2011 at 17:28

2 Answers 2

1

Not the eof() function again! You want:

while( getline(dictFile,dictionary[index]) ) {
  index++;
}

(assuming dictionary is something sensible, which it might not be) because eof() does not predict if the next read will work.

And where oh where are people picking up this use of eof() from? It's like a disease!

Sign up to request clarification or add additional context in comments.

3 Comments

Saw it somewhere... I will immediately make a mental note not to use it again. However, this fix produces the same error.
I prefer writing this as: for ( string line; getline(input,line); ) { ... } because it is more idiomatic, allows post-processing of line contents and is uniform across container types.
@Andre I can't say that I see it as idiomatic - I expect a for loop to loop from one known value to another, not to be indeterminate.
0

This is how I'd do the whole program, if my goal were terseness and not performance.

// read the dictionary 

vector<string> dictionary;
{
  ifstream dictionary_file("dictionary.txt");
  istream_iterator<string> begin(dictionary_file);
  istream_iterator<string> end;
  while( begin != end )
    dictionary.push_back( *begin++ );
  sort( dictionary.begin(), dictionary.end() );
}

// read the input file and test against the dictionary

{
  ifstream input_file("input.txt");
  istream_iterator<string> begin(input_file);
  istream_iterator<string> end;
  while( begin != end )
  {
    string input = *begin++;
    vector<string>::iterator it = lower_bound( dictionary.begin(), dictionary.end(), input );
    if( it != dictionary.end() && *it == input )
      cout << input << " found!" << endl;
    else
      cout << input << " not found!" << endl;
  }
}

2 Comments

Using a std::set would probably give you much better performance, make the intent clearer, as well as simplify it: dictionary.find(word) != dictionary.end() is much clearer than using lower_bound() on a vector!
You are right that std::set would read more clearly, but you are wrong that it would have better performance. std::set and a sorted std::vector should have exactly the same performance when searching for an item.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.