user3444650
user3444650

Reputation: 117

Split lines by delimiter to parse a text file

I'm writing a program that takes a txt file like this:

foo.txt:

Aaaa/NGACG/NGAA//
Aaab/AGGGC//
Aaac/CTN/AGGC/NNA//

And in each line it stores the ID (Aaa..) into a vector (once for each value), and the values separated by / into strings.

So the first line would be:

    foo.push_back("Aaaa");
    string bar = NGACG;
    foo.push_back("Aaaa");
    string bar2 = NGAA;

The pseudocode is something like this:

while (not end of file)
{
    while (not end of line)
    {
        while (next char isn't /)
        {
            temporary string x += char
        }
        foo.push_back(string)       //ID

        while (next char isn't /)
        {
            string bar += char      //value
        }
    }
}

My pseudocode is obviously flawed, but that's the general idea of what I want to do. I've looked up guides on how to parse, but nothing really works for my purposes. How can I do this without being completely inefficient? I can't think of how to write this without using an arbitrary number of while loops

Upvotes: 1

Views: 490

Answers (2)

Peter - Reinstate Monica
Peter - Reinstate Monica

Reputation: 16049

You can read the lines (or the whole file) into simple char arrays and use the lines you have read directly: simply replace / with '\0' and point char pointers to the next char into the very lines, without copying anything. The null bytes terminate the "values" between the slashes in the original data and are C strings of their own for all intents and purposes.

Upvotes: 0

Serge Ballesta
Serge Ballesta

Reputation: 149115

You can do it the good old C way with fgets and strtok:

char line[SIZE];   // make sure SIZE is greater than your longest input line ...
char *ix;
while(fgets(line), SIZE, fdin) {
    line[strcspn("\n")] = '\0'; // remove EOL
    ix = strtok(line, "/");
    foo.push_back(string(ix));
    string bar = string(strtok(NULL, "/"));
    string bar2 = string(strtok(NULL, "/"));
    ...
}

Or you can use a stringstream and std::getline with the delimiter parameter:

string line;
while(getline(fdin, line)) {
    string temp, bar, bar2;
    istringstream is(line);
    getline(is, temp, '/');
    foo.push_back(temp);
    getline(is, bar);
    getline(is, bar2);
    ...
}

Of course, you should add tests for error conditions...

Upvotes: 1

Related Questions