0

I have a string object that is something like:

string test = "
[3, 4, 8, 10, 10]\n[12]\n[12, 10,\n 20]
"

And am trying to parse it into the 3 separate arrays equaling [3, 4, 8, 10, 10], [12], and [12,10, 20]. I have parsed Comma separated integers into an array before but how do I go about parsing this one. Unfortunately the data I have can have newlines mid array otherwise I would use the "getline" function(when reading the file into the string) and simply ignore the brackets.

It seems like I need to first get each array into its own string delimited by brackets, and then parse each of those by comma delimination into an array of integers. Would this work?

If so, how do I split up the string by brackets into a previously unknown number of other strings?

user3376740
  • 19
  • 1
  • 4

3 Answers3

4

You can use streams and std::getline() for this as std::getline() takes a delimiter as a parameter:

int main()
{
    std::string test = "[3, 4, 8, 10, 10]\n[12]\n[12, 10,\n 20]";

    // make data a stream (could be a std::ifstream)
    std::istringstream iss(test);

    // working vars
    std::string skip, item;

    // between square braces
    // skip to the opening '[' then getline item to the closing ']'
    while(std::getline(std::getline(iss, skip, '['), item, ']'))
    {
        // item = "3, 4, 8, 10, 10"

        // store numbers in a vector (not array)
        std::vector<int> v;

        // convert item to a stream
        std::istringstream iss(item);

        // separated by commas
        while(std::getline(iss, item, ','))
            v.push_back(std::stoi(item));

        // display the results
        std::cout << "list:" << '\n';
        for(auto i: v)
            std::cout << "\t" << i << '\n';
    }
}

Output:

list:
    3
    4
    8
    10
    10
list:
    12
list:
    12
    10
    20
Galik
  • 47,303
  • 4
  • 80
  • 117
1

If you have already read the whole thing into a string, the following should work:

#include <iostream>
#include <string>

using namespace std;

int main() {
  string test = "[3, 4, 8, 10, 10]\n[12]\n[12, 10,\n 20]";
  size_t start = 0;  // first position in the string

  // find the first occurance of "]"
  size_t pos = test.find("]");

  while ( pos != string::npos ) {
    // move to position after "]"
    // so it is included in substring
    pos += 1;

    // create a substring
    string subStr = test.substr(start, pos-start);

    // remove newlines from new string
    size_t newLinePos = subStr.find("\n");
    while ( newLinePos != string::npos ) {
      subStr.erase(newLinePos,1);
      newLinePos = subStr.find("\n");
    }

   // here is the substring, like: [12, 10, 20]
    cout << "Substring: " << subStr << endl;

    // update start position for next substring
    start = pos;
    // find next occurrance of "]"
    pos = test.find("]", pos);
  }

}
Signal Eleven
  • 231
  • 1
  • 6
0

One way to approach this is to use an explode() function. Implementations of explode() will break a string into multiple strings based on a given delimiter. It's not the most efficient method, but it can make a lot of intuitive sense.

See: Is there an equivalent in C++ of PHP's explode() function?

Community
  • 1
  • 1
Jonny D
  • 2,244
  • 15
  • 22
  • 1
    If he can, maybe you can too… – Potatoswatter Apr 26 '15 at 01:07
  • An implementation that I post here would be more noise instead of just answering the question. In my opinion, in this case he's better off choosing an implementation than if I chose it for him. explode() is a non-specific concept and can be taken multiple directions depending on his personal requirements. – Jonny D Apr 26 '15 at 22:09
  • 1
    You didn't suggest to implement it, only to find something with a search engine. Anyway, whatever. – Potatoswatter Apr 27 '15 at 02:10
  • Though a search term is enough to let the OP solve the problem, I'd agree that it's not typical SO ettiquette. So I've linked to a related question instead. – Jonny D Apr 27 '15 at 13:55