CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Sep 2012
    Posts
    12

    Searching file for string

    I'm in a beginner C++ course, and have gotten stuck on an assignment I've been given. This is the part I'm having trouble with right now:

    The program then asks the user for a search string, which may contain white space. The program should search the file for every occurrence of the search string. When the string is found, the line that contains it should be displayed in the following format
    nnnnn:Line Contents
    That is the line number of the line, 5 columns wide, right justified, followed by a colon, followed by the contents of the line.


    And this is what I've got so far:
    Code:
    #include<iostream>
    #include<fstream>
    #include<string>
    #include<iomanip>
    using namespace std;
    
    int main(int argc, char *argv[])
    {
    	ifstream inFile;
    	string fileName,
    		   text,
    		   toFind;
    	size_t found = 0;
    
    	if (argc > 1) 
    		fileName = argv[1];
    	else 
    	{
    		cout << "File Name: ";
    		getline(cin, fileName);
    	};
    	inFile.open(fileName.data());
    
    	if (!inFile)
    	{
    		cout << "Error, cannot open the file";
    		exit(1);
    	};
    
    	cout << "Enter string to find: ";
    	cin >> toFind;
    	inFile >> text;
    	int lineNum = 1;
    	while (getline(inFile, text))
    	{
    		found = (text.find(toFind));
    		if (found != 0)
    		{
    			cout << setw(5) << lineNum << ":";
    			cout << text << endl;
    		}
    		lineNum++;
    		found = 0;
    	};
    
    	inFile.close();
    
    	return(0);
    }
    But this doesn't work. It prints everything in the file, not just the lines where the string is found. Can anyone help me understand what I need to do differently?

  2. #2
    Join Date
    Aug 2009
    Posts
    440

    Re: Searching file for string

    Instead of comparing found against 0, you need to compare it against string::npos.

  3. #3
    Join Date
    Sep 2012
    Posts
    12

    Re: Searching file for string

    Okay...I looked up what npos is and I'm not totally sure how to use it. Sorry if this is really basic, but we haven't covered that yet and I'm having a hard time understanding how exactly to use it.

  4. #4
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Searching file for string

    string::npos is a constant of type size_t, which essentially is nothing else than an unsigned int. So, your test whether the search string has been found could look like this:

    Code:
    		found = text.find(toFind) != string::npos;
    with the type of found changed to bool. However, since you're only using the found status stored in the variable in a single if condition anyway, you can eliminate the variable found altogether and do the check right inside the if instruction, like this:

    Code:
    		if (text.find(toFind) != string::npos)
    		{
    			// ...
    		}
    IMO that's not only shorter overall, but also clearer.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  5. #5
    Join Date
    Sep 2012
    Posts
    12

    Re: Searching file for string

    However, since you're only using the found status stored in the variable in a single if condition anyway, you can eliminate the variable found altogether and do the check right inside the if instruction, like this:

    Code:
    		if (text.find(toFind) != string::npos)
    		{
    			// ...
    		}
    IMO that's not only shorter overall, but also clearer.
    I used this, but it still prints the entire file, not just the line where the text is found

  6. #6
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Searching file for string

    Works for me. Using the .cpp source file itself as the input file to search through:

    Name:  2012-11-09_201322.png
Views: 800
Size:  6.7 KB
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  7. #7
    Join Date
    Sep 2012
    Posts
    12

    Re: Searching file for string

    Oh, okay, I realized my issue is that I was entering a two word phrase and it was only searching for the first word. How can I get it to accept the space character and search for phrases as well? I changed cin >> toFind to getline(cin, toFind), but it's still not working.

  8. #8
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Searching file for string

    Exactly that should do the trick, and it does for me. I simply copy-pasted your proposed command from your post into my version of your program here. Could it be you made the change but then forgot to rebuild the program?
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  9. #9
    Join Date
    Sep 2012
    Posts
    12

    Re: Searching file for string

    I'm not sure what I was messing up, but I finally got it to work with this:

    Code:
    #include<iostream>
    #include<fstream>
    #include<string>
    #include<iomanip>
    #include<algorithm>
    using namespace std;
    
    bool nocase_compare (char c1, char c2)
    {
        return toupper(c1) == toupper(c2);
    }
    
    int main(int argc, char *argv[])
    {
    	int lineNum = 1, wordNum = 0;
    	ifstream inFile;
    	string fileName,
    		   text,
    		   toFind;
    	size_t found;
    	static const size_t npos = -1;
    
    	if (argc > 1) 
    		fileName = argv[1];
    	else 
    	{
    		cout << "File Name: ";
    		getline(cin, fileName);
    	};
    	inFile.open(fileName.data());
    
    	if (!inFile)
    	{
    		cout << "Error, cannot open the file";
    		exit(1);
    	};
    
    	
    	cout << "Enter string to find or type // to quit: ";
    	getline(cin, toFind);
    		while (toFind != "//")
    		{
    			inFile >> text;
    			wordNum = 0;
    			while (getline(inFile, text))
    			{
    				string::iterator pos;
    				pos = search (text.begin(),text.end(), 
                           toFind.begin(),toFind.end(),
                            nocase_compare); 
    				if (pos == text.end()) 
    				{
    				} 
    				else 
    				{
    					cout << setw(5) << lineNum << ":";
    					cout <<  text << endl;
    					wordNum++;
    				}
    				lineNum++;
    			}
    			cout << "Number of times found: " << wordNum << endl;
    			cout << "Enter string to find or type // to quit: ";
    			getline(cin, toFind);
    		}
    	cin.ignore();	
    
    	inFile.close();
    
    	return(0);
    }
    But I can't get the search to repeat. It asks for the string again, but doesn't search again. It also doesn't exit immediately if the user types "//", they have to type it again before it will close. Why isn't the while (toFind != "//") loop working?

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Searching file for string

    Quote Originally Posted by taymaxi View Post
    But I can't get the search to repeat. It asks for the string again, but doesn't search again. It also doesn't exit immediately if the user types "//", they have to type it again before it will close. Why isn't the while (toFind != "//") loop working?
    I think it's time that you started to debug your code, instead of just writing code, running it, and asking "what's wrong?" Debugging is part and parcel of learning how to write computer programs. It is a mandatory process.

    What is the value of "toFind" when the while loop is entered? What is the flow of your program when you run it? If you single-stepped through the program with the debugger, where does the program flow take you? All of these questions are answered by debugging your code.

    Regards,

    Paul McKenzie

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured