C++ Code: Searching for a specific string

Click For Summary

Discussion Overview

The discussion revolves around writing a C++ program that searches for a specific word in an input file and counts its occurrences, outputting the result to an output file. Participants explore various coding issues, syntax errors, and logic problems related to file handling and string comparison in C++.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant requests help with a C++ program that counts occurrences of a user-specified word in a file, highlighting issues with their current implementation.
  • Another participant points out that the use of char pointers for variable declarations may lead to undefined behavior and suggests using char values instead.
  • A participant inquires about the header files being used, indicating issues with code compilation in their environment.
  • One participant shares their header files and expresses uncertainty about the correctness of their code, indicating a need for further assistance.
  • Another participant describes modifications made to the original code, including changes to how characters are read from the file, but expresses confusion about checking for the word "fox".
  • A participant identifies errors in variable declarations and logic, emphasizing the need to initialize variables before use and suggesting alternative methods for reading characters to find the target word.
  • One participant shares their working code, which includes a method for reading strings and checking for the target word, but the code appears to be incomplete.

Areas of Agreement / Disagreement

Participants generally agree on the need to correct variable declarations and logic in the code. However, there are multiple competing views on the best approach to implement the word search functionality, and the discussion remains unresolved regarding the most effective coding strategy.

Contextual Notes

Limitations include potential misunderstandings about string handling in C++, the need for proper initialization of variables, and the handling of file input/output operations. Some participants express uncertainty about their suggestions and the correctness of their code modifications.

Who May Find This Useful

Readers interested in C++ programming, particularly those working on file handling and string manipulation, may find this discussion beneficial.

ermines
Messages
45
Reaction score
0
umm, anyone who could help me write a code wherein, given an input file, it searches for a word inputed by the user, then outputs the result (how many times it appeared in the input file) in an output file. This program also uses 2 command line arguments. The first argument is the word to search for, the second is the name of the input file.

Below is my code which DOESN'T work. Any ideas how to correct it...?

int main (int argc, char *argv[])
{
ifstream inStream;
ofstream outStream;
if (argc != 3) //argc should be 3 for correct execution
count << "Please enter 2 valid command-line arguments! \n";
else
{
ifstream the_ifile(argv[2]); //argv[2] is the filename to open
ofstream the_ofile("counter.txt");
if (!the_ifile.is_open()) //checking to see if file opening succeeded
count << "Could not open file\n";
else
{
char *v, *w, *x, *y, *z;
int occurances=0;
do{
inStream >> v >> w >> x >> y >> z;
do{
occurances++;
}while(v==" " && w=="f" && x=="o" && y=="x" && z==" ");
}while(!inStream.eof());
the_ofile << "FILE: " << argv[2] << endl;
the_ofile << "SEARCHKEY: " << argv[1] << endl;
the_ofile << "OCCURANCES: " << occurances-1 << endl;
the_ofile << "---------------------------------------" << endl;
}
inStream.close();
outStream.close();
return 0;
}
}

basically, I'm trying to view from the input file 5 characters at once and check if it is the word " fox ". If it is, the variable occurances would be incremented by one. It does this until it reaches the end of the file. As more "fox" occurs, occurances would be successively incremented.
 
Physics news on Phys.org
I'm a bit rusty on this stuff, but ...

at this line: char *v, *w, *x, *y, *z;
you have declared v,w,x,y,z as pointers to chars.

In this line: inStream >> v >> w >> x >> y >> z;
Since v,w,x,y,z are pointers, then inStream will assign data, of type char pointer, to the variables, rather than char values.
These pointers will then have rogue addresses in them and are liable to crash your system if used inappropriately.

In this line: }while(v==" " && w=="f" && x=="o" && y=="x" && z==" ");
v,w,x,y,z are now being compared to strings. But strings contain a NULL end-of-string character, so will never compare with char values. (Or, char pointers!)

I think your problem may be solved if you re-declare v,w,x,y,z as chars rather than char pointers, and, in the last line mentioned, change the strings to chars by replacing the double quotes with single quotes.

Like I said, I'm a bit rusty on this, so I'm not certain if my comments are correct, however, HTH.
 
Last edited:
As a matter of interest, what header files are you using ?

I've been trying to run your code with Dev-C but it's not compiling :frown:
 
here my header files...

#include <fstream>
#include <iostream>
#include <cstdlib> //for exit

i'll take your advice. actually, that's also the part I'm very doubtful off. I'm still trying to workout to fix it too.
 
Thanks
extra characters to make up the 10-char minumum message limit
 
anyway, i did some modifications in the file since its messy like having two declarations of ifstream (my bad here :frown: ).

#include <fstream>
#include <iostream>
#include <cstdlib> //for exit

using namespace std;

int main (int argc, char *argv[])
{
if (argc != 3) //argc should be 3 for correct execution
count << "Please enter 2 valid command-line arguments! \n";
else
{
ifstream the_ifile(argv[2]); //argv[2] is the filename to open
ofstream the_ofile("counter.txt");
if (!the_ifile.is_open()) //checking to see if file opening succeeded
count << "Could not open file\n";
else
{
char q, r, s;
char f, o, x;
int occurances=0;
do{
the_ifile.get(q);
count << q;
the_ifile.get(r);
count << r;
the_ifile.get(s);
count << s;
while((q==f || r==f || s==f) && (q==o || r==o || s==o) && (q==x || r==x || s==x))
{
occurances++;
count << q << r << s; //for debugging
}
}while(!the_ifile.eof());
the_ofile << "FILE: " << argv[2] << endl;
the_ofile << "SEARCHKEY: " << argv[1] << endl;
the_ofile << "OCCURANCES: " << occurances-1 << endl;
the_ofile << "---------------------------------------" << endl;
}
the_ifile.close();
the_ofile.close();
return 0;
}
}

basically, i changed my loop conditions. i used the_ifile.get() to get the character in the input file one at a time. having 3 of them makes it check the first three characters. the only problem is my condition for the second loop. how do i know what the character the the_file.get() holds? I tried setting it to equal fox or "fox" or like the one above but it doesn't work.

also, i did:

do {
occurances++;
}while(q==f && r==o && s==x);

but all it does is check the number of characters in the file...:(

so anyone who has a bright idea. it would really be nice if the forum members who are well-versed in c++ would read this thread :)
 
Last edited:
I'll point out two errors for the moment.

In the line: char f, o, x;

You have declared three char variable, but f,o,x are the names of the variables and you have assigned no values to them!
(At the least you should have had: char f='f', o='o', x='x';

So at this line: while((q==f || r==f || s==f) && (q==o || r==o || s==o) && (q==x || r==x || s==x))

f,o,x can have any values.


Also, at this line: while((q==f || r==f || s==f) && (q==o || r==o || s==o) && (q==x || r==x || s==x))

r=='f', s=='o', q=='x' will satisfy the conditions being tested and lead to the char sequence qrs =="xfo" giving a true condition and hence wrongly incrementing occurrences.


I think there are basically two ways of doing this.

1) Read one char at a time:
If the 1st char read is a space then
read a second char else read for the 1st char variable again
if 2nd char is a 'f' then
read a third char else reset the file pointer by 1 byte/char and go back to the beginning.
if 3rd char is a 'o' ...

2) Read 5 chars at a time
If the 5 chars ==" fox " then an occurrence has been found
else
reset the file pointer by 4 bytes/chars and start from the beginning again
 
thanks for all the advice, Fermat :smile: .

here's my working code...

#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib> //for exit

using namespace std;

int main (int argc,char *argv[])
{
if(argc!=3) //argc should be 3 for correct execution
{
count << "Please enter 2 valid command-line arguments! \n";
}
else
{
ifstream the_ifile(argv[2]); //argv[2] is the filename to open
ofstream the_ofile("counter.txt", ios::app);
if (!the_ifile.is_open()) //checking to see if file opening succeeded
{
count << "Could not open file\n";
}
else
{
int w,x,y,z;
int occurances=0;
int i,n;

n=strlen(argv[1]);

char string[n+1];
do //Does an infinite loop if the input file has a new
{ //line. The file should have a continuous sentence.
the_ifile.get(string,n+1);
if(strstr(string, argv[1])!=NULL)
{
occurances++;
}
the_ifile.seekg(i++);
}while(!the_ifile.eof());

the_ofile << "FILE: " << argv[2] << endl;
the_ofile << "SEARCHKEY: " << argv[1] << endl;
the_ofile << "OCCURANCES: " << occurances << endl;
the_ofile << "---------------------------------------" << endl;
}

the_ifile.close();
the_ofile.close();

return 0;
}
}

my only problem now is that the code does an infinite loop in the input file has many paragraphs. It can only check files which only has one paragraph, meaning having one long continuous sentence. So how do i fix that...
 
From the description of what happens, I think this "n=strlen(argv[1]);" may be the problem.

strlen() will return the length of a string. Strings are null-terminated sequences of characters. The file may have been saved, by the word processor you used, as a series of strings, each string being one paragraph. Try to ensure that the file is saved in DOS/ASCII mode rather than text mode, say.

If this doesn't work, you can find out the length of a file using tellg().

int l = File.tellg(ios::end);
 

Similar threads

  • · Replies 2 ·
Replies
2
Views
5K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 7 ·
Replies
7
Views
2K
  • · Replies 15 ·
Replies
15
Views
3K
  • · Replies 17 ·
Replies
17
Views
6K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 16 ·
Replies
16
Views
2K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 5 ·
Replies
5
Views
4K