0

I am using the vector to store all the lines (parsing from a CSV file), which matched with the string that I am looking for (via string.find()!=string::npos).

But, the results didn't print out all the lines which contain the string.

CSV file:

fruit, 1000, abc, d890, 1234
fruit, 1432, abc, d890, 1234
fruit, 8923, abc, d890, 1234
fruit, 1454, abc, d890, 1234
fruit, 2574, abc, d890, 1234
fruit, 1000, abc, d890, 1234
fruit, 1000, abc, d890, 1234
water, 1000, abc, d890, 1234
water, 1000, abc, pat1, 1432
water, 1000, abc, pat2, 8923
water, 1000, abc, pat3, 1454
water, 1000, abc, pat4, 2574
water, 1000, abc, d890, 1234

The output which I want is as below:

fruit, 1432, abc, d890, 1234
fruit, 8923, abc, d890, 1234
fruit, 1454, abc, d890, 1234
fruit, 2574, abc, d890, 1234
water, 1000, abc, pat1, 1432
water, 1000, abc, pat2, 8923
water, 1000, abc, pat3, 1454
water, 1000, abc, pat4, 2574

But, actual output is

water, 1000, abc, pat1, 1432
water, 1000, abc, pat2, 8923
water, 1000, abc, pat3, 1454
water, 1000, abc, pat4, 2574

Codes as below:

    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <string>
    #include <vector>
    #include <windows.h>

    using namespace std;

    void splitter(vector<string> HK, vector<string>& CH)
{
    for(unsigned int i = 0; i < HK.size(); i++)
    {
        char sep = ',';
        string s = HK[i];
        for(size_t p = 0, q = 0; p != s.npos; p = q)
        {
            CH.push_back(s.substr(p + (p != 0), (q = s.find(sep, p + 1)) - p - (p != 0)));
        }
    }
}

    int main()
    {
        ifstream iFile("C:\\abc.csv");
        string line;

        //Opening may fail, perform checking
        if(!iFile)
        {
            cout << "Error, could not open file." << endl;
            return -1;
        }

        string lookForStr[] = {"pat1", "pat2", "pat3", "pat4"};

        //create vector to store BLT of parent and child
        vector<string> lookForStrVec;
        vector<string> lookForStrVecNext;
        vector<string> lookForStrVecNext1;
        vector<string> lookForStrVecNext11;     

        while(!iFile.eof())
        {
            getline(iFile, line);

            for(unsigned int i = 0; i < 4; ++i)                
                {
                    if(line.find(lookForStr[i]) != string::npos)
                    {
                        lookForStrVec.push_back(line);
                    }
                }

                splitter(lookForStrVec, lookForStrVecNext);

                for(unsigned int i = 0; i < lookForStrVecNext.size(); i += 5)
                {
                    if(line.find(lookForStrVecNext[i + 4]) != string::npos)
                    {
                        string str = lookForStrVecNext[i + 4];
                        lookForStrVecNext1.push_back(str);
                    }
                }

                for(unsigned int i = 0; i < lookForStrVecNext1.size(); ++i)
                {
                    if(line.find(lookForStrVecNext1[i]) != string::npos)
                    {
                        lookForChildStrNext11.push_back(line);
                    }
                }
            }
        }

        cout << endl << "print all lines with matched string..." << endl;
        for(unsigned int i = 0; i < lookForStrVecNext11.size(); ++i)
        {
            cout << lookForChildVecNext11[i] << endl;
        }       

        system("pause");
    }
John5012
  • 29
  • 9
  • [eof() in while is bad](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – Andreas DM May 11 '16 at 02:21
  • 1
    Seeing `string lookForStr[] = {"pat1", "pat2", "pat3", "pat4"};` I don't expect the four others to match. – O'Neil May 11 '16 at 02:22
  • @AndreasDM, any suggestion? – John5012 May 11 '16 at 02:28
  • @O'Neil, actually that is the first part, which I attempted to look for the 1432, 8923, 1454, 2574. After that, my target is to printout all lines which contains 1432, 8923, 1454, 2574. But, I don't understand why only the lower part of lines with these number got print out, instead of lines which contains these four numbers?Any suggestion? – John5012 May 11 '16 at 02:32

1 Answers1

0

Here is a simpler approach, printing the lines containing one of:
"1432", "8923", "1454", "2574"

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <vector>

int main()
{
    std::ifstream file("file.txt");
    if (!file.is_open()) {
        std::cout << "Couldn't open file\n";
        return -1;
    }

    std::vector<std::string> find { "1432", "8923", "1454", "2574" };

    std::string line;
    while (std::getline(file, line)) {
        bool found = false;
        std::for_each(begin(find), end(find), [&](std::string s) {
            std::string::size_type n = 0;
            n = line.find(s);
            if (n != std::string::npos) {
                found = true;
                return;
            }
        });

        if (found)
            std::cout << line << '\n';
    }
}

Which prints the expected result:

fruit, 1432, abc, d890, 1234
fruit, 8923, abc, d890, 1234
fruit, 1454, abc, d890, 1234
fruit, 2574, abc, d890, 1234
water, 1000, abc, pat1, 1432
water, 1000, abc, pat2, 8923
water, 1000, abc, pat3, 1454
water, 1000, abc, pat4, 2574
Andreas DM
  • 9,654
  • 6
  • 31
  • 58
  • Thanks @Andreas DM. But, what if I want to make the codes to search for the numbers, instead of hard-coding it? Is there any way if doing it? – John5012 May 11 '16 at 06:27
  • @John5012 I'm not sure what you mean, you can't blindly find the numbers. In the example above, we checking if one of the numbers are present in the string. Why make it more complicated? – Andreas DM May 11 '16 at 06:33
  • Andreas DM, this is because I have more than 1 csv file, and each is different (the numbers are different from 1 csv file to another). That's why the code need to parse the csv file, which have to start with "water", then look at the fifth column, which is the target number. Then, the code have to remember the number and check other line, which start with "fruit", to check whether the line contain the number, if yes, then it has to be displayed. – John5012 May 12 '16 at 00:41