-2

I have written the following code to find the number of "ATA" in a text that is read to a string as "GCTATAATAGCCATA". The count returned should be 3 but it returns 0. When I check in debugger the string for text is initially created. However, when an empty string is passed to the function patternCount. Am I reading the contents of the file into the string text correctly?

#include <iostream>
#include <fstream>
#include <string>

using namespace std;
void  patternCount(string text, string pattern);

int main()
{
    string text;
    fstream file_("test.txt");
    if(file_.is_open())
    {
        while(getline(file_,text))
        {
            cout << text << '\n';
        }
        file_.close();
    }
    cout << "Enter a string ";
    string pattern;
    getline(cin, pattern);
    patternCount(text, pattern);


    return 0;
}

void patternCount(string text, string pattern)
{
    int count = 0;
    size_t nPos = text.find(pattern, 0);
    while (nPos != string::npos)
    {
        nPos = text.find(pattern, nPos + 1);
        ++count;
    }
    cout << "There are " << count <<" " << pattern << " in your text.\n";
}
R. A.
  • 1
  • Can you provide the content of `test.txt`? It matters a lot. – iBug Jul 19 '18 at 04:59
  • 1
    Your variable `text` does not contain your file, it contains only the last line of the file (you read a new line into it each time through the loop overwriting the previous one). – Galik Jul 19 '18 at 05:04
  • This line is the only thing in the file: GCTATATAGCCATA – R. A. Jul 19 '18 at 05:05
  • 1
    Try doing cout << text << '\n'; after the while loop and then problem should be obvious – PapaDiHatti Jul 19 '18 at 05:06
  • 1
    Does your file end with an empty line? – Galik Jul 19 '18 at 05:06
  • If your file contains the pattern followed by an end-of-line marker then the last line is empty. If you typed in the pattern and then hit the return key, that's what you will have. – Galik Jul 19 '18 at 05:07
  • Yes it does end with an empty line – R. A. Jul 19 '18 at 05:08
  • Fixed the problem using this link: https://stackoverflow.com/questions/195323/what-is-the-most-elegant-way-to-read-a-text-file-with-c – R. A. Jul 19 '18 at 05:18
  • You do know you can do this with a simple `grep`? I.e. `grep -o ATA << – Toby Speight Jul 19 '18 at 09:39

3 Answers3

0

So if I understand correctly, you're not sure if you're reading correctly the contents from the file test.txt. If you want to read every content, then try this instead:

ifstream file_("test.txt");
string s,text;
file_>>s;
text=s;
while(file_>>s)
{
    text=text+" "+s;
}

This should probably work. Note that reading from a file like filename>>string only reads till the first space. That's why I'm using the while. You can also use getline(), which reads the whole text with spaces. Also note that you should include fstream. Printing out the text should help more as well.

P. B.
  • 19
  • 3
0
#include <iostream> 
#include <fstream> 
#include <string>
using std::cout;
using std::cerr;
using std::string;

int count = 0; // we will count the total pattern count here

void patternCount(string text, string pattern);

int main() { 
cout << "Enter a string "; 
string pattern; 
std::getline(cin, pattern); 
string text; 
fstream file_("test.txt");
if(file_.is_open()){
   while(std::getline(file_,text)) 
      patternCount(text,pattern);
   file_.close(); 
}else
   cerr<<"Failed to open file";
cout << "There are " << count <<" " << pattern << " in your text.\n";
return 0;
}

void patternCount(string text, string pattern){
 size_t nPos = text.find(pattern, 0); 
 while (nPos != string::npos) { 
 nPos = text.find(pattern, nPos + 1); 
 ++count; 
 }
}

The Problem

Your code was good, there were no bugs in patternCount function.

But You were reading the file in an incorrect way. See, everytime you call std::getline(file_, text), the old result of the _text are overwritten by new line. So, in the end of the loop, when you pass text to patternCount function, your text only contains the last line of the file.


The Solution

You could have solved it in two ways:

  1. As mentioned above, you could run patternCount() to each line in while loop and update a global count variable.
  2. You could append all the lines to text in while loop and at last call the patternCount function.

Whichever you prefer, I have implemented the first, while second one is in other answers.

Community
  • 1
  • 1
coder3101
  • 3,175
  • 1
  • 19
  • 24
  • 1
    You really ought to avoid `using namespace std` - it is a bad habit to get into, and [can silently change the meaning of your program](/q/1452721) when you're not expecting it. Get used to using the namespace prefix (`std` is intentionally very short), or importing *just the names you need* into the *smallest reasonable scope*. – Toby Speight Jul 19 '18 at 09:35
  • And it's probably better to have `patternCount` return a value which the caller can use to update `count`, rather than sharing state using a global (i.e. `count += patternCount(line)`). – Toby Speight Jul 19 '18 at 09:37
  • I understand but I typed this answer on a mobile and so I couldn't edit the answer a lot. Just copied the OP's code and edited a bit. Yes pattern... Can return also but as I said, I tried to keep my response close to OP's code with correction. Thanks for Pointing BTW, I will edit answer when I log with a PC – coder3101 Jul 19 '18 at 09:40
0

This code just counts the number of occurrence of input string in the last line of text file. If that line is empty or no does not contain the string, The output result will be 0. But I guess the OP wants to search a whole file, in which case the main function need be fixed accordingly.

std::ifstream file{"test.txt"};
std::ostringstream text;
std::copy(std::istream_iterator<char>{file}, std::istream_iterator<char>{},std::ostream_iterator<char>{text});
//...
patternCount(text.str(), pattern);
Red.Wave
  • 1,427
  • 6
  • 8
  • Copying the whole file into memory is usually a poor choice, if the file might be large. – Toby Speight Jul 19 '18 at 09:35
  • @TobySpeight I aggree. but this is just a hint, not the complete solution. This is a short and simple demo of some std features. After all, programming needs a little bit of practice too. – Red.Wave Jul 19 '18 at 09:39