rushik wrote:
Hello,
I am writing one application in which I am getting data as a string "
10 | 20 | 30 | 40 | 50" now my aim is to parse those string, split it
by pipe '|' and get integer outputs in some array or other data
structure.....
do anybody worked in the same functionality, then please let me know.
Thanks,
Rushik.
If however you prefer doing it yourself, the std::string is well
capable of pumping out a parser. Keep in mind that you should use
std::string::size_type to hold those values returned by find_first_of
-like member functions. You can then std::istringstream the substrings
to generate the numbers. The std::string class includes a panoply of
member functions and ctors that will let you substring at construction
time or using assign(...), etc.
Here is one nasty example that uses 2 functions, one to populate a
container of relevant substrings and another templated function to
convert the substrings into a container of numbers. It'll work with
any seperator including spaces, comma, colon, etc or any combination of
these. The error checking is rudimentary at best (you need to supply
the correct seperator).
Take note that t_track is used to prevent find_first_of from rolling up
to std::string::npos ( a costly operation on some implementations).
Also, there is most likely better ways of doing this.
check out boost's tokenizer, for example.
#include <iostream>
#include <ostream>
#include <string>
#include <vector>
#include <sstream>
#include <stdexcept>
void parser( std::vector<std::string>& r_v,
const std::string& s,
const std::string& r_sep )
{
std::string::size_type t_track = s.find_last_of(r_sep);
if ( t_track == std::string::npos )
{
throw std::exception(); // no sep found
}
std::string s_temp(s); // decapitating string
while ( t_track != std::string::npos )
{
std::string::size_type t_size = s_temp.find_first_of(r_sep);
std::string s_add(s_temp, 0, t_size);
std::cout << "s_add = " << s_add << std::endl;
r_v.push_back(s_add);
t_track = t_track - s_add.size() - r_sep.size(); // npos?
s_temp.assign(s_temp, t_size + r_sep.size(), s_temp.size());
std::cout << "s_temp = " << s_temp << std::endl;
}
r_v.push_back(s_temp); // push last one
}
template< typename T >
void converter( std::vector<std::string>& r_vs,
std::vector<T>& r_vt )
{
typedef std::vector<std::string>::iterator VIter;
VIter iter = r_vs.begin();
for (iter; iter != r_vs.end(); ++iter)
{
T t;
std::istringstream iss(*iter);
iss >t;
r_vt.push_back(t);
}
}
int main()
{
std::string s("10 | 20 | 30 | 40 | 50");
// std::string s("-11 20 -3 2 4 3 1 -6");
std::vector<std::stringvs;
try
{
parser(vs, s, " | ");
std::vector<intvn;
converter<int>(vs, vn);
for (size_t i = 0; i < vn.size(); ++i)
{
std::cout << "vn[ " << i << "] = ";
std::cout << vn.at(i) << std::endl;
}
}
catch ( const std::exception& e )
{
std::cout << "Error !" << std::endl;
}
return 0;
}
/*
s_add = 10
s_temp = 20 | 30 | 40 | 50
s_add = 20
s_temp = 30 | 40 | 50
s_add = 30
s_temp = 40 | 50
s_add = 40
s_temp = 50
vn[ 0] = 10
vn[ 1] = 20
vn[ 2] = 30
vn[ 3] = 40
vn[ 4] = 50
*/