Search word from file C++

Hi guys,
I have been looking all over internet. I'm a noob with C++ so all I can find don't make sense to me and not working the way I wanted. Maybe someone here can help me to start?

I wan't to create kind of grep with C++. I find out how to search word from files text with regex, but I wanted to do it using something more practical.

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
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>

using namespace std;

string line;
string target;
ifstream infile("file.txt");
int line_counter = 0;
int pos = 0;

int main(int argc, char* argv[])
{
    cout << "Enter something to find: ";
    cin >> target;

    while (infile && pos != string::npos)
    {
        line_counter++;

        getline(infile, line);

        pos = line.find(target);

        //if found
        if (pos != string::npos)
        {
            cout << target << " found at position " << pos << " in line #" << line_counter << " of the text file. ";
        }
    }

    //if not found
    if (pos == string::npos)
    {
        cout << target << " not found in ye' text file. ";
    }

}
Last edited on
Perhaps:

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
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main(int argc, char* argv[])
{
    if (argc != 3)
    {
        cout << "Usage: " << argv[0] << " search_string filename\n";
        return 1;
    }

    ifstream infile(argv[2]);
    if (!infile)
    {
        cout << "Cannot open " << argv[2] << '\n';
        return 1;
    }

    int lineno = 0;
    string line;
    while (getline(infile, line))
    {
        ++lineno;
        auto pos = line.find(argv[1]);
        if (pos != string::npos)
            cout << lineno << ":" << pos << ": " << line << '\n';
    }
}

a starting point might be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main(int argc, char* argv[])
{
    if(argc < 3) //if the user did not provide enough command line inputs.  
     //you can, and should probably, do more exhaustive input validation and maybe have them
     //do flags as well rather than rely on the order of the arguments to be correct. 
      {
         cout << "usage:  mygrep filename word"
         return 1;
      }
 
    ifstream infile(argv[1]);  //attempt to open the first target as the file 
    string target = argv[2];   //assign target from the second argument
    
    ...


after you get this working, you can allow them to enter more words and iterate your search,
for each argument (not counting the first one that is the file name)
search for the word, show the lines...
and more files too, for that matter, for each file, for all the words... (at this point you MUST put flags on what each thing is, up to now, you can use the order of args)
just note that arg[] are c-strings. you can assign a string a c-string, so promotion lets you do things more normally, or you can process it as-is depending on what you use it for (see how I just used it in the file name but moved it to a string in the target?). I plan to use target a lot, but the file name only in one statement ever, no need to upcast it.
Last edited on
jonnin, just wanted to point out that your if statement should be <= 2, not just < 2. And you can directly just assign string target = argv[2];
thanks. I fixed them! I was trying to show that the args are char* but found a better way to say it with just words.
Last edited on
@dutch I'm confused where I put my file. How the program knows where to search for?

Program only prints me path, but how I can include user input to this and search it?

@jonnin I will search for this!
Last edited on
The program searches from what the working directory is that it runs inside of.
So if the program is running inside C:\programs\foo.exe, then it can access "C:\programs\file.txt" as just the local path "file.txt".

To see the working directory of your process, a quick temporary trick is to call
system("cd"); on windows and system("pwd"); on *nix systems.
Last edited on
Ganado right! Got it. Still don't know how to process this..
Sorry, I'm confused to what the exact issue is? Can you be specific, what does running dutch's program show you exactly? You're meant to run it with command-line parameters.

e.g.
mygrep "search string" my_file.txt
Last edited on
Oh right! I tried to run this in VS, but sure it's not working the same.. :) Thank you!
Another problem came out. The code is printing me lines but not content?

e.g.
1
2
3
myprog.exe "day" test.txt
5 // Empty right heree
18
Last edited on
Can you show the exact code you're running? Or is it verbatim still dutch's post?
Scorpia wrote:
I tried to run this in VS, but sure it's not working the same

If you run an app from the VS IDE you can still use command-line parameters. You have to add them to the project's setup. For VS 2019:

Main Menu->Project->Properties.

Configuration Properties->Debugging->Command Arguments.

Convoluted, yes, but that is the price of using an IDE.
Ganado, it's verbatim with cutch's post

Furry Guy, nice to know, thanks!
dutch's code in the previous post does display the content of the found line:

 
 cout << lineno << ":" << pos << ": " << line << '\n';


which displays
line no : position in line : contents of line

For a test file, I get:


c:\MyProgs>test64 dog test.txt
6:0: dog
13:0: dog22
20:0: dog333
27:0: dog44


If this isn't what you get - or not as wanted, post your current code.

I think I have some issues just with my path and files. I use a local file and OneDrive so something messing up. Now it's working like I want to!

But, another problem!
Can I make this as a sub program?
Last edited on
You can do something like:

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
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

void grep(int argc, char* argv[])
{
	ifstream infile(argv[2]);

	if (!infile)
		cout << "Cannot open " << argv[2] << '\n';

	int lineno {};
	string line;

	while (getline(infile, line)) {
		++lineno;
		const auto pos {line.find(argv[1])};
		if (pos != string::npos)
			cout << lineno << ":" << pos << ": " << line << '\n';
	}
}

int main(int argc, char* argv[])
{
	if (argc != 3) {
		cout << "Usage: " << argv[0] << " search_string filename\n";
		return 1;
	}

	grep(argc, argv);
}

Ok, I see. How about I hace in main another subprogram call?
Last edited on
What do you want the program to do? If the program has more than one purpose, should you have multiple programs - rather than having one program trying to do multiple things?

You could do something like:

1
2
3
4
5
6
7
int main(int argc, char* argv[])
{
    if (argc == 3)
        Search_grep(argc, argv);
    else
        Big_sub_string();
}


But it depends upon what you trying to achieve.
Ok, I'm looking for options but it seems it's more effective the way it already is. Just wondering! :) Thank you for your help!
Last edited on
Topic archived. No new replies allowed.