cpd1
cpd1

Reputation: 789

A better way of parsing a string for numbers in brackets?

I've tried searching on here / Google to find a more optimal way of processing an input that I need to handle. This is an example...

[1 5 0 50 100 60] [2 4 1 0 40 50]

The numbers are random but I know how many bracketed sets there are beforehand. Also, I know for certain that the format will always be the same...

6 numbers which are enclosed by brackets

I have something working already where I get the input into a line and I then iterate character by character checking...

1) Outer for loop that accounts for the number of bracketed sets

2) First to see if it is a space, '[', ']'

3) If it isn't, get that number and store it

4) then start checking for space again

5) Store the next etc

6) Till I reach ']' and continue the loop

But I feel like there needs to be a better / cleaner way of handling the parsing.

sample code...

    char c = line[position];

    while (c == '[' || c == ']' || cc == ' '){
        position++;
        c = line[position];
    }

    string firstStr;

    while (c != ' '){
        firstStr += c;
        position++;
        c = line[position];
    }

    first = atoi(firstStr.c_str());

    while (c == ' '){
        position++;
        ch = line[position];
    }

    string secondStr;

    while (c != ' '){
        secondStr += c;
        position++;
        c = line[position];
    }

    second = atoi(secondStr.c_str());

Upvotes: 0

Views: 587

Answers (1)

Sam Varshavchik
Sam Varshavchik

Reputation: 118330

Yes, I'd say that this is too complicated for the simple reason that the C++ library already contains optimized implementations of all algorithms that are needed here.

std::string line;

That's your input. Now, let's parse it.

#include <algorithm>

auto b=line.begin(), e=line.end();

while ((b=std::find(b, e, '[')) != e)
{
    auto n_start=++b;

    b=std::find(b, e, ']');

    auto your_six_numbers_are_in_here=std::string(n_start, b);

    // Now, do whatever you want with your numbers.
}

Since you "know for certain" that your input is valid, most aspects of input validation are no longer an issue, and the above should be sufficient.

The your_six_numbers_are_in_here string may or may not contain leading or trailing spaces. How to get rid of them, and how to extract the actual numbers is a separate task. Now, since you know "for certain" that your input will be valid, then this becomes a simple matter of:

std::istringstream i(your_six_numbers_are_in_here);

int a, b, c, d, e, f;

i >> a >> b >> c >> d >> e >> f;

It goes without saying that if you do not know "for certain" that your input will be valid, additional work will be needed, here.

Upvotes: 2

Related Questions