Parsing a string of integers into multiple integers

I have a string "n,n,n" where each n is a value 0 to 19.

I know I can use find(), substr(), and atoi() to breakout the integers, but I saw somewhere someone using istringstream (I think) with code something like " buffer >> int1 >> int2 >> int3 ". Does this make sense to anyone? Any help or pointers would be appreciated.

I saw the answer to this somewhere, but I've search extensively and I can't find it. I could look through browser history for a couple hours, but was hoping somebody knows this one.

~dave

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
void breakOut(string str, int &i, int &j, int &k){
  //declare local variables
  istringstream buffer(str);
  buffer >> i >> j >> k;
}
 
...

 //Initialize cave;
    // after great frustration trying to randomize the cave, I'm hard coding it.
  saRoom[0] = "1,10,19"; saRoom[1] = "0,2,6"; saRoom[2] = "1,3,13"; saRoom[3] = "2,4,8";
  saRoom[4] = "3,5,15"; saRoom[5] = "4,6,12"; saRoom[6] = "1,5,7"; saRoom[7] = "6,8,18";
  saRoom[8] = "3,7,9"; saRoom[9] = "8,10,17"; saRoom[10] = "0,9,11"; saRoom[11] = "10,12,14";
  saRoom[12] = "5,11,13"; saRoom[13] = "2,12,14"; saRoom[14] = "11,13,15"; saRoom[15] = "4,14,16";
  saRoom[16] = "15,17,19"; saRoom[17] = "9,16,18"; saRoom[18] = "7,17,19"; saRoom[19] = "0,16,18";

  //Place objects (continued)
  breakOut(saRoom[iERm], iC1, iC2, iC3);
  cout << "iErm = " << iERm <<".  iC1 = " << iC1 << ".  iC2 = " << iC2 << ". iC3 = " << iC3 << ".\n";
}


Output :
iErm =7. iC1 = 6. iC2 = 0. iC3 = 0.
Last edited on
You could use C++11's std::to_string

or:

1
2
3
4
std::stringstream ss;
        ss << 32; // The integer
        std::string str;
        ss >> str;
You could use C++11's std::to_string

or

1
2
3
4
std::stringstream ss;
        ss << 32; // The integer
        std::string str;
        ss >> str;
@Bourgond Aries - I'm not sure how your answer fits my question.

@Everyone - I ended up doing it the hard way:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void breakOut(string str, int &i, int &j, int &k){
  //declare local variables
  int lc1, lc2;
  string sTemp;
  size_t zPos;

  zPos = str.find(',');
  lc1 = static_cast<int>(zPos);
  zPos = str.find(',', zPos+1);
  lc2 = static_cast<int>(zPos);
  sTemp = str.substr(0,lc1);
  i = atoi(sTemp.c_str());
  sTemp = str.substr(lc1+1,(lc2-lc1-1));
  j = atoi(sTemp.c_str());
  sTemp = str.substr(lc2+1);
  k = = atoi(sTemp.c_str());
}


I'd still like to know the elegant solution that allows me to use something like
 
buffer >> i >> j >> k;
Last edited on
Oh, sorry, I think I misunderstood.

istringstream and stringstream's operator >> separate by whitespaces.

You could simply use std::replace_if and replace all occurences of ',' in your string, and then feed it into your original breakOut function.
Yes, replace comma with space:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>

    using namespace std;

void breakOut(string str, int &i, int &j, int &k);

int main()
{
    std::string saRoom[20] = {
        "1,10,19",  "0,2,6",    "1,3,13",   "2,4,8",
        "3,5,15",   "4,6,12",   "1,5,7",    "6,8,18",
        "3,7,9",    "8,10,17",  "0,9,11",   "10,12,14",
        "5,11,13",  "2,12,14",  "11,13,15", "4,14,16",
        "15,17,19", "9,16,18",  "7,17,19",  "0,16,18"
    };

    int a, b, c;

    for (int i=0; i<20; i++)
    {
        breakOut(saRoom[i], a,  b, c);
        cout << setw(10) << saRoom[i]
             << setw(4) << a << setw(4) << b << setw(4) << c << endl;
    }

    return 0;
}

void breakOut(string str, int &i, int &j, int &k)
{
    // replace all commas with spaces
    size_t pos = 0;
    while ((pos = str.find(',',pos)) != string::npos)
         str[pos] = ' ';
    istringstream buffer(str);
    buffer >> i >> j >> k;
}
   1,10,19   1  10  19
     0,2,6   0   2   6
    1,3,13   1   3  13
     2,4,8   2   4   8
    3,5,15   3   5  15
    4,6,12   4   6  12
     1,5,7   1   5   7
    6,8,18   6   8  18
     3,7,9   3   7   9
   8,10,17   8  10  17
    0,9,11   0   9  11
  10,12,14  10  12  14
   5,11,13   5  11  13
   2,12,14   2  12  14
  11,13,15  11  13  15
   4,14,16   4  14  16
  15,17,19  15  17  19
   9,16,18   9  16  18
   7,17,19   7  17  19
   0,16,18   0  16  18
If you don't mind a slightly longer compile time you can get much faster results using Boost Spirit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>

#include <boost/spirit/include/qi.hpp>

void breakOut(const std::string& str, int &i, int &j, int &k);

int main()
{
    using namespace std;
    string saRoom[20] = {
        "1,10,19",  "0,2,6",    "1,3,13",   "2,4,8",
        "3,5,15",   "4,6,12",   "1,5,7",    "6,8,18",
        "3,7,9",    "8,10,17",  "0,9,11",   "10,12,14",
        "5,11,13",  "2,12,14",  "11,13,15", "4,14,16",
        "15,17,19", "9,16,18",  "7,17,19",  "0,16,18"
    };

    int a, b, c;

    for (int i=0; i<20; i++)
    {
        breakOut(saRoom[i], a,  b, c);
        cout << setw(10) << saRoom[i]
             << setw(4) << a << setw(4) << b << setw(4) << c << endl;
    }

    return 0;
}

void breakOut(const std::string& str, int &i, int &j, int& k)
{
    using namespace boost::spirit::qi;
    std::vector <int> results;
    phrase_parse( str.begin(), str.end(), (int_ % ','), space, results );
    i = results[ 0 ];
    j = results[ 1 ];
    k = results[ 2 ];
}

Hope this helps.
Topic archived. No new replies allowed.