-2

I'm very new to C++.

I'm trying to populate a vector with elements from a tab delimited file. What is the easiest way to do that?

Thanks!

Aisha
  • 11
  • 2
  • Hint: TAB's count as whitespaces. Reading from whitespace delimited text is trivially supported by the `>>` operator. – πάντα ῥεῖ Mar 04 '16 at 02:01
  • 1
    Trivial right up to "Hi there!\tfishbeen" Am I two tokens or three? If you have to deal with this, [std::getline has an overload that allows you to specify a delimiter to use in place of end of line.](http://en.cppreference.com/w/cpp/string/basic_string/getline) Use that overload with `'\t'` and start reading. – user4581301 Mar 04 '16 at 02:05

2 Answers2

0

There could be many ways to do it, simple Google search give you a solution.

Here is example from one of my projects. It uses getline and read comma separated file (CSV), I let you change it for reading tab delimited file.

ifstream fin(filename.c_str());
string buffer;

while(!fin.eof() && getline(fin, buffer))
{
    size_t prev_pos = 0, curr_pos = 0;
    vector<string> tokenlist;
    string token; 
    // check string
    assert(buffer.length() != 0);

    // tokenize string buffer.
    curr_pos = buffer.find(',', prev_pos);

    while(1) {

        if(curr_pos == string::npos)
            curr_pos = buffer.length();

        // could be zero
        int token_length = curr_pos-prev_pos;

        // create new token and add it to tokenlist.
        token = buffer.substr(prev_pos, token_length);
        tokenlist.push_back(token);

        // reached end of the line
        if(curr_pos == buffer.length())
            break;

        prev_pos = curr_pos+1;
        curr_pos = buffer.find(',', prev_pos);
    }
}

UPDATE: Improved while condition.

vcp
  • 962
  • 7
  • 15
  • 2
    `while(!fin.eof())` has a few problems, biggest here being only catching end of file. I recommend `while(getline(fin, buffer))` which catches every error case you're likely to care about. – user4581301 Mar 04 '16 at 02:21
  • You don't need the test for eof. It is implied in the state of `fin` after `getline`. In `while(getline(...))`, getline returns the stream. `while` tests the streamwith the stream's boolean operator. If anything went wrong, the boolean operator returns false. Here is a good write p on what's happening behind the scenes: http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool – user4581301 Mar 04 '16 at 06:39
0

This is probably the easiest way to do it, but vcp's approach can be more efficient.

std::vector<string> tokens;
std::string token;
while (std::getline(infile, token, '\t')
{
    tokens.push_back(token);
}

Done. You can actually get this down to about three lines of code with an input iterator and a back inserter, but why?

Now if the file is cut up into lines and separated by tabs on those lines, you also have to handle the line delimiters. Now you just do the above twice, one loop for lines and an inner loop to parse the tabs.

std::vector<string> tokens;
std::string line;
while (std::getline(infile, line)
{
    std::stringstream instream(line)
    std::string token;
    while (std::getline(instream, token, '\t')
    {
        tokens.push_back(token);
    }
}

And if you needed to do line, then tabs, then... I dunno... quotes? Three loops. But to be honest by three I'm probably looking at writing a state machine. I doubt your teacher wants anything like that at this stage.

user4581301
  • 33,082
  • 7
  • 33
  • 54