Tokenise a string in cpp

Hi I have a string like

12;13;14|aa=12;bb=15;cc=18


I need to store the values 12,13,14 in a list,
aa,bb,cc values in a list and
mapping of aa,bb,cc values to 12,15,18 in another list.



Can anyone suggest me how to achieve this
How about this:

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
42
43
44
45
46
47
48
49
#include <vector>
#include <map>
#include <string>

using namespace std;

int main() 
{
   char input[] = "12;13;14|aa=12;bb=15;cc=18";
   char delim[] = ";|";
   char* tok, *next_tok;
   vector<int> v;
   map<string, int> m;

   tok = strtok_s(input, delim, &next_tok);

   while (tok)
   {
      if (strstr(tok, "="))
      {
         char* subnext_tok;
         char* subtok = strtok_s(tok, "=", &subnext_tok);

         try
         {
            int a = atoi(subnext_tok);
            m.insert(map<string, int>::value_type(subtok, a));
         }
         catch(...)
         {
         }
      }
      else
      {
         try
         {
            int a = atoi(tok);
            v.push_back(a);
         }
         catch(...)
         {
         }
      }

      tok = strtok_s(NULL, delim, &next_tok);
   }

   return 0;
}
Using more C++-ish solutions, it can be done with boost.spirit in a single pass:

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
42
43
44
45
46
47
48
#include <iostream>
#include <string>
#include <list>
#include <map>
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phx = boost::phoenix;

int main()
{
    std::string str = "12;13;14|aa=12;bb=15;cc=18";

    std::list<int> numbers;
    std::list<std::string> strings;
    std::map<std::string, int> mappings;

    if ( qi::phrase_parse(str.begin(), str.end(),
         // begin grammar
         // int_ % ';' >> '|' (semicolon-sparated list of integers, followed by '|')
         // push_back each int_ into numbers, and omit from final result
         qi::omit[ qi::int_[phx::push_back(phx::ref(numbers), qi::_1)] % ';' >> '|' ] >>
         // ( char_ >> char_ >> '=' int_ ) % ';'
         // adapt each char_ >> char_ as string, push_back into strings
         ( qi::as_string[qi::char_ >> qi::char_][phx::push_back(phx::ref(strings), qi::_1)]
            >> '=' >> qi::int_ ) % ';',
         // end grammar
         ascii::space, mappings))
    {
        // output
        std::cout << "Parsing succeeded\nlist of numbers: ";
        for(int n : numbers)
            std::cout << n << ' ';
        std::cout << "\nlist of strings: ";
        for(auto& str : strings)
            std::cout << str << ' ';
        std::cout << "\nthe map: ";
        for(auto& p : mappings)
            std::cout << " { " << p.first << " -> " << p.second << " } ";
        std::cout << '\n';
    }
    else
    {
        std::cout << "Parsing failed\n";
    }
}

$ ./test
Parsing succeeded
list of numbers: 12 13 14
list of strings: aa bb cc
the map:  { aa -> 12 }  { bb -> 15 }  { cc -> 18 }
Last edited on
Hi ajh32 and cubbi,
Thanks for the replies both of the solutions worked for me.

I have one more concern..

can I pass the elements of vector list as bind variables in a db query?
If so How can I do that?


here the values 12,13,14 in vector list..I need to pass them as bind variables in a sql query..

Thanks in advance!!
Topic archived. No new replies allowed.