Search word from file C++

Feb 16, 2021 at 6:12pm
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 Feb 17, 2021 at 12:30pm
Feb 16, 2021 at 7:54pm
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';
    }
}

Feb 16, 2021 at 8:00pm
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 Feb 16, 2021 at 8:10pm
Feb 16, 2021 at 8:08pm
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];
Feb 16, 2021 at 8:10pm
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 Feb 16, 2021 at 8:12pm
Feb 16, 2021 at 8:24pm
@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 Feb 16, 2021 at 8:31pm
Feb 16, 2021 at 8:33pm
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 Feb 16, 2021 at 8:33pm
Feb 16, 2021 at 8:34pm
Ganado right! Got it. Still don't know how to process this..
Feb 16, 2021 at 8:36pm
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 Feb 16, 2021 at 8:38pm
Feb 16, 2021 at 8:43pm
Oh right! I tried to run this in VS, but sure it's not working the same.. :) Thank you!
Feb 16, 2021 at 9:01pm
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 Feb 17, 2021 at 12:32pm
Feb 16, 2021 at 9:12pm
Can you show the exact code you're running? Or is it verbatim still dutch's post?
Feb 17, 2021 at 1:14am
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.
Feb 17, 2021 at 10:15am
Ganado, it's verbatim with cutch's post

Furry Guy, nice to know, thanks!
Feb 17, 2021 at 10:35am
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.

Feb 17, 2021 at 11:48am
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 Feb 17, 2021 at 12:32pm
Feb 17, 2021 at 12:01pm
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);
}

Feb 17, 2021 at 12:14pm
Ok, I see. How about I hace in main another subprogram call?
Last edited on Feb 17, 2021 at 12:33pm
Feb 17, 2021 at 12:22pm
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.
Feb 17, 2021 at 12:26pm
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 Feb 17, 2021 at 12:27pm
Topic archived. No new replies allowed.