-1

I am trying to write a code which lists all words used in a text file without repeating. I succeeded to list all the words but I always get repeating ,the if statement line 17 always gives the value of 0.I have no idea why , the words are listed properly in the vector. Any suggestion ?

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

class reading {
public:
    string word;
    vector<string> words;
};

int checkifexist(string word) {
    reading readingobject;
    bool exist = false;
    for (int i = 0; i < readingobject.words.size(); i++) {
        if (word == readingobject.words[i]) {
            exist = true;
            break;
        }
    }

    return exist;
}

int main() {

    reading readingobject;
    ifstream inFile;
    inFile.open("Book.txt");

    if (inFile.fail()) {
        cout << "file didn't open" << endl;
        exit(1);
    }
    readingobject.word.resize(1);
    while (!inFile.eof()) {
        inFile >> readingobject.word;
        if (checkifexist(readingobject.word) == 1)
            continue;

        cout << readingobject.word << endl;
        readingobject.words.push_back(readingobject.word);
    }

    return 0;
}
Mohammad
  • 1
  • 4
  • 4
    `reading readingobject;` creates a new object, whose `words` vector is empty – UnholySheep Sep 18 '20 at 20:46
  • 1
    [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/) – Remy Lebeau Sep 18 '20 at 20:48
  • @UnholySheep ,I added another line readingobject.word.resize(1); ,but it doesn't work and the vector gets a resize every time in the while loop. – Mohammad Sep 18 '20 at 20:53
  • You are missing the point. You are creating a 2nd `reading` object that you should not be creating in the first place, you need to get rid of it. – Remy Lebeau Sep 18 '20 at 20:55
  • In `int checkifexist(string word) {` the `reading readingobject;` is a totally separate variable than the one with the same name in `int main()`. These variables are in different scopes. Instead `int checkifexist(string word)` should be a class member of the reading class. – drescherjm Sep 18 '20 at 20:56

1 Answers1

0

Inside of checkifexist(), you are creating a new reading object, whose words vector is empty, so there is nothing for the loop to do, and the function returns 0.

You need to instead pass in the reading object from main() as an input parameter, eg:

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

class reading {
public:
    vector<string> words;
};

bool checkifexist(const reading &readingobject, const string &word)
{
    for (size_t i = 0; i < readingobject.words.size(); ++i) {
        if (word == readingobject.words[i]) {
            return true;
        }
    }
    return false;

    /* alternatively:
    return (std::find(readingobject.words.begin(), readingobject.words.end(), word) != readingobject.words.end());
    */
}

int main()
{
    reading readingobject;
    string word;

    ifstream inFile;
    inFile.open("Book.txt");

    if (!inFile) {
        cout << "file didn't open" << endl;
        return 1;
    }

    while (inFile >> word) {
        if (checkifexist(readingobject, word))
            continue;

        cout << word << endl;
        readingobject.words.push_back(word);
    }

    return 0;
}

Alternatively, when it comes to tracking unique elements, you can use a std::set instead of a std::vector, eg:

#include <iostream>
#include <fstream>
#include <set>

using namespace std;

class reading {
public:
    set<string> words;
};

int main()
{
    reading readingobject;
    string word;

    ifstream inFile;
    inFile.open("Book.txt");

    if (!inFile) {
        cout << "file didn't open" << endl;
        return 1;
    }

    while (inFile >> word) {
        if (readingobject.words.insert(word).second)
            cout << word << endl;
    }

    return 0;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770