Question

I have a text file that displays the following:

John    Smith    21    UK
David   Jones    28    FRANCE
Peter   Coleman  18    UK

and I am trying to strip each individual element into a vector array. I have tried using the getline function with a tab delimiter but it stores every element. For example:

getline (f, line, '\t');
records.push_back(line);

How can I seperate it line by line? The idea is to perform a search and output the corresponding line. A search for Jones will print out the second line for example.

This is what I have so far but as you can see, it's not giving me the desired outcome:

string sString;
string line;
string tempLine;
string str;
vector<string> records;

cout << "Enter search value: " << endl;
cin >> sString;

cout << "\nSEARCHING\n\n";
ifstream f("dataFile.txt");

while (f)
    {
    while(getline (f, tempLine))
    {
       getline (f, line, '\t');
       records.push_back(line);
    }
    for(int i=0; i < records.size(); i++)
    {
       if(sString == records[i]) {
        cout << "RECORD FOUND" << endl;
        for(int j=0; j < records.size(); j++)
        {
            cout << j;
            cout << records[j] << "\t";
        }
        }
    }

}
f.close();
Was it helpful?

Solution

The first getline extracts a complete line from the input. The second extracts one field from the next line. If you want to recover the lines broken down into fields, you should do:

std::vector<std::vector<std::string>> records;
std::string line;
while ( std::getline( f, line ) ) {
    records.push_back( std::vector<std::string>() );
    std::istringsream fieldParser( line );
    std::string field;
    while ( std::getline( fieldParser, field ) ) {
        records.back().push_back( field );
    }
}

This will result in a vector of records, where each record is a vector of fields. More often, you would want to use a struct for the record, and do a bit more parsing on the line, e.g.:

struct Field
{
    std::string firstName;
    std::string lastName;
    int age;
    std::string country;
};
std::vector<Field> records;
std::string line;
while ( std::getline( f, line ) ) {
    std::istringsream fieldParser( line );
    Field field;
    fieldParser >> field.firstName >> field.lastName >> field.age >> field.country >> std::skipws;
    if ( !fieldParser || fieldParser.get() != EOF ) {
        //  Error occurred...
    } else {
        records.push_back( field );
    }
}

(Something this simple will only work if none of the fields may contain white space. But it's simple to extend.)

OTHER TIPS

You are doing getline into tempLine which eats a whole line, then you are doing a different getline in the loop as well. That's a big part of why it doesn't work--you are simply throwing away tempLine which contains a lot of your data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top