How do you search a document for a string in c++?

10,565

Solution 1

while(infile >> word)
{
    if(word == keyWord)
    {
        cout << word << endl;
        count++;
    }
}

This would do the job. Please read about streams more.

Solution 2

If all you want to do is count the number of keywords in a file then:

int count = std::count(std::istream_iterator<std::string>(infile),
                       std::istream_iterator<std::string>(),
                       keyword);

If you want to read words.
But also want to print the line numbers then somthing like this should work:

std::string      line;
std::ifstream    infile("plop");
int              lineNumber = 0;

while(std::getline(infile, line)) 
{
    ++lineNumber ;
    std::stringstream   linestream(line);
    int hits = std::count(std::istream_iterator<std::string>(linestream),
                          std::istream_iterator<std::string>(),
                          keyword);
    if (hits != 0)
    {
        std::cout << "Line: " << lineNumber << "   Matches(" << hits << ")\n";
    } 
    count  += hits;
} 
Share:
10,565
Soully
Author by

Soully

Am majoring in Computer Science, emphasizing on programming. I really enjoy coding in visual basic, or what little of it I've used, but as I only have ever programmed in that and C++, I don't quite have a favorite yet. I just finished my general ed requirements, and have just recently started working on my major. I asked my first question on this site and within minutes did I have not one reply, but five! And each answer was very helpful, I instantly added this site to my bookmarks, as finding one as helpful as this is near impossible...save this site and use it! It's great for not only beginners, but veteran programmers alike!

Updated on June 04, 2022

Comments

  • Soully
    Soully almost 2 years

    Here's my code so far:

    #include<iostream>
    #include<string>
    #include<fstream>
    
    using namespace std;
    
    int main()
    {
        int count = 0;
        string fileName;
        string keyWord;
        string word;
    
    
        cout << "Please make sure the document is in the same file as the program, thank you!" 
             << endl << "Please input document name: " ;
        getline(cin, fileName);
        cout << endl;
    
        cout << "Please input the word you'd like to search for: " << endl;
        cin >> keyWord;
        cout << endl;
        ifstream infile(fileName.c_str());
        while(infile.is_open())
        {
            getline(cin,word);
            if(word == keyWord)
            {
                cout << word << endl;
                count++;
            }
            if(infile.eof())
            {
                infile.close();
            }
    
        }
        cout << count;
    
    }
    

    I'm not sure how to go to the next word, currently this infinite loops...any recommendation?

    Also...how do I tell it to print out the line that that word was on?

    Thanks in advance!

  • Billy ONeal
    Billy ONeal about 14 years
    That runs the loop per word instead of per line. Not downvoting because I'm not sure if that's what the OP wants though...
  • Soully
    Soully about 14 years
    Need to loop per word, but afterwards need to print out the line number that the word was located on.
  • Martin York
    Martin York about 14 years
    You should NOT check for EOF in the loop like that. It is not true until after you try and read past the end of the file. So if you have read the whole file EOF is still false so the loop is entered. Then the >> operator will fail attempting to read a word and the value in word is probably unspecified when you entered the if condition. Loop using this: while(infile >> word) {} The loop will only be entered if the >> operators succedes in reading a word from the file.
  • Martin York
    Martin York about 14 years
    This still fails, as the EOF is only true after you try and read past the end of file. Use: while( infile >> word) {}
  • Billy ONeal
    Billy ONeal about 14 years
    @Martin York: How so? We're both using operator bool so I fail to see how it fails :)
  • Baltasarq
    Baltasarq about 14 years
    Yep. It would be better to read before entering, and then again just before the en of the loop. The term is "reading ahead". But I didn't want to change so many things in his program.
  • Martin York
    Martin York about 14 years
    The problem is you will then perform a read inside the loop. Which may potentially fail because of EOF. So inside the loop you will do a read followed by another explicit test to see if EOF has been reached if it has then you will need to exit the loop before any processing is done. In the "standard pattern" you do the read as part of the while, thus if there is no more data the read cause the EOF to become true and thus the loop is never entered.
  • Martin York
    Martin York about 14 years
    You have to remember that the second to last read from a stream reads UP-TO the EOF without triggering it. (So reading the last line of a file will read up-to the EOF (without triggering EOF). So there is no data left in the file BUT the loop will still be entered. But the first read that tries to read a file with no data will set the EOF flag inside the loop.
  • Billy ONeal
    Billy ONeal about 14 years
    @Marting York: Ah, I see now :) I'd still use std::getline but it does need to go in the loop, I agree.
  • Martin York
    Martin York about 14 years
    Change your code above and I will delete the comments if you want.
  • Martin York
    Martin York about 14 years
    The trouble is that your example is the standard anti-pattern for reading a stream via a loop. Also it is incorrect as if the keyword appears on the last line it will potentially be counted twice (depending on whether >> operator clears word before testing the streams state or after).
  • Martin York
    Martin York about 14 years
    std::count using stream iterators will do the same thing :-)