Connecting Tech Pros Worldwide Forums | Help | Site Map

Parsing string

tech
Guest
 
Posts: n/a
#1: Jun 27 '08
Hi, I need to parse a string used to represent a time and then
populate
a simple time struct. The time string will always be this format

23:45.45 ie hours separated from mins by ':' and minutes separated
from seconds by '.'
The string will be 8 chars in len. I've come up with some simple code
below
but am wondering do i really need a wstringstream and a string to do
this. Can
the parsing just be done with a wstringstream.

struct TIMESTRUCT
{
unsigned short Hour;
unsigned short Minute;
unsigned short Second;
}

bool TimeParser(const std::wstring& time, TIMESTRUCT& st)
{
std::wistringstream tmp;
// a time string must be 8 chars in len
assert(time.size() == 8);

tmp.str(time.substr(0, 2));
tmp >st.Hour;
if (time[2] != ':') return false;
tmp.clear();
tmp.str(time.substr(3, 2));
tmp >st.Minute;
if (time[5] != '.') return false;
tmp.clear();
tmp.str(time.substr(6, 2));
tmp >st.Second;
return true;
}

int main()
{
TIMESTRUCT st;
std::wstring t(L"23:34.45");
TimeParser(t, st);
return 0;
}

Mirco Wahab
Guest
 
Posts: n/a
#2: Jun 27 '08

re: Parsing string


tech wrote:
Quote:
Hi, I need to parse a string used to represent a time and then
populate a simple time struct. The time string will always be
this format 23:45.45 ie hours separated from mins by ':' and
minutes separated from seconds by '.'
The string will be 8 chars in len. I've come up with some simple code
below but am wondering do i really need a wstringstream and a
string to do this. Can
the parsing just be done with a wstringstream.
This would work with istringstream if you change
its formal argument from
Quote:
bool TimeParser(const std::wstring& time, TIMESTRUCT& st)
to bool TimeParser(const std::string& time, TIMESTRUCT& st)

and the actual data from
Quote:
int main()
{
TIMESTRUCT st;
std::wstring t(L"23:34.45");
to std::string t("23:34.45");


BTW, some people tend to do almost everythin
in regular expressions (which will be there
soon and are long available via boost).

Your TimeParser would be much simpler, like:

...
#include <boost/regex.hpp>
using namespace boost;
...

bool TimeParser(const std::string& time, TIMESTRUCT& st)
{
cmatch m;
if(regex_match(time.c_str(), m, regex("^(\\d{2}):(\\d{2})\\.(\\d{2})$"))) {
st.Hour = atoi(m[1].first);
st.Minute = atoi(m[2].first);
st.Second = atoi(m[3].first);
return true;
}
return false;
}

The required format "dd:dd.dd" would be checked by
the regular expression and all would be fine.

Regards

M.
James Kanze
Guest
 
Posts: n/a
#3: Jun 27 '08

re: Parsing string


On Jun 25, 2:30 pm, Mirco Wahab <wa...@chemie.uni-halle.dewrote:
Quote:
tech wrote:
BTW, some people tend to do almost everythin
in regular expressions (which will be there
soon and are long available via boost).
Quote:
Your TimeParser would be much simpler, like:
Quote:
...
#include <boost/regex.hpp>
using namespace boost;
...
Quote:
bool TimeParser(const std::string& time, TIMESTRUCT& st)
{
cmatch m;
if(regex_match(time.c_str(), m, regex("^(\\d{2}):(\\d{2})\\.(\\d{2})$"))) {
st.Hour = atoi(m[1].first);
st.Minute = atoi(m[2].first);
st.Second = atoi(m[3].first);
return true;
}
return false;
}
Quote:
The required format "dd:dd.dd" would be checked by
the regular expression and all would be fine.
Two small nits: first, regex_match can take iterators, so you
can just write:
if ( regex_match( time.begin(), time.end(), m, expr ) ) ...
And since the expression is a constant, that's how I'd write it:
static regex const expr( "^(\\d{2}):(\\d{2})\\.(\\d{2})$" ) ;
(at the start of the function, before the if).

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
tech
Guest
 
Posts: n/a
#4: Jun 27 '08

re: Parsing string


On Jun 25, 4:37*pm, James Kanze <james.ka...@gmail.comwrote:
Quote:
On Jun 25, 2:30 pm, Mirco Wahab <wa...@chemie.uni-halle.dewrote:
>
>
>
>
>
Quote:
tech wrote:
BTW, some people tend to do almost everythin
in regular expressions (which will be there
soon and are long available via boost).
Your TimeParser would be much simpler, like:
* *...
* *#include <boost/regex.hpp>
* *using namespace boost;
* *...
* *bool TimeParser(const std::string& time, TIMESTRUCT& st)
* {
* *cmatch m;
* *if(regex_match(time.c_str(), m, regex("^(\\d{2}):(\\d{2})\\.(\\d{2})$"))) {
* * * st.Hour * = atoi(m[1].first);
* * * st.Minute = atoi(m[2].first);
* * * st.Second = atoi(m[3].first);
* * * return true;
* *}
* *return false;
* }
The required format "dd:dd.dd" would be checked by
the regular expression and all would be fine.
>
Two small nits: first, regex_match can take iterators, so you
can just write:
* * if ( regex_match( time.begin(), time.end(), m, expr ) ) ...
And since the expression is a constant, that's how I'd write it:
* * static regex const expr( "^(\\d{2}):(\\d{2})\\.(\\d{2})$" ) ;
(at the start of the function, before the if).
>
--
James Kanze (GABI Software) * * * * * * email:james.ka...@gmail.com
Conseils en informatique orientée objet/
* * * * * * * * * *Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34- Hide quoted text -
>
- Show quoted text -
Thanks guys but i was wondering whether i could do my simple function
with just
a stringstream rather with a string aswell.
Mirco Wahab
Guest
 
Posts: n/a
#5: Jun 27 '08

re: Parsing string


tech wrote:
Quote:
Thanks guys but i was wondering whether i could do my simple function
with just a stringstream rather with a string aswell.
I don't completely understand what you
want and what you are trying to
accomplish. What means:
/with just a stringstream rather with a string aswell/

If you only want to get rid of the w_ functions, just
don't use them:

bool TimeParser(const std::string& time, TIMESTRUCT& st)
{
assert(time.size() == 8); // a time string must be 8 chars
char a ,b;
std::istringstream tmp(time);
tmp > st.Hour >a > st.Minute >b >st.Second;
return a == ':' && b == '.' ? true : false;
}

int main()
{
TIMESTRUCT st;
std::string t("03:34.45");
TimeParser(t, st);
return 0;
}

But maybe there's something else?

Regards

M.

Mirco Wahab
Guest
 
Posts: n/a
#6: Jun 27 '08

re: Parsing string


James Kanze wrote:
Quote:
On Jun 25, 2:30 pm, Mirco Wahab <wa...@chemie.uni-halle.dewrote:
Quote:
> bool TimeParser(const std::string& time, TIMESTRUCT& st)
> {
> cmatch m;
> if(regex_match(time.c_str(), m, regex("^(\\d{2}):(\\d{2})\\.(\\d{2})$"))) {
> st.Hour = atoi(m[1].first);
> st.Minute = atoi(m[2].first);
> st.Second = atoi(m[3].first);
> return true;
> }
> return false;
> }
>
Two small nits: first, regex_match can take iterators, so you
can just write:
if ( regex_match( time.begin(), time.end(), m, expr ) ) ...
This would require the smatch overloaded 'regex_match',
which returns std::string objects in matches and does,
in this case, also provide a version that uses the
plain std::string:

bool TimeParser(const std::string& time, TIMESTRUCT& st)
{
using namespace boost;
smatch m;
static regex r("^(\\d{2}):(\\d{2})\\.(\\d{2})$");
if(regex_match(time, m, r)) {
st.Hour = atoi(m[1].str().c_str());
st.Minute = atoi(m[2].str().c_str());
st.Second = atoi(m[3].str().c_str());
return true;
}
return false;
}

The use of the smatch-overloaded regex_... requires
an additional step to extract the resulting values,
compare it to the original version:

bool TimeParser(const std::string& time, TIMESTRUCT& st)
{
using namespace boost;
cmatch m;
if(regex_match(time.c_str(), m, regex("^(\\d{2}):(\\d{2})\\.(\\d{2})$"))) {
st.Hour = atoi(m[1].first);
st.Minute = atoi(m[2].first);
st.Second = atoi(m[3].first);
return true;
}
return false;
}

Which looks (imho) less cluttered.
Quote:
And since the expression is a constant, that's how I'd write it:
static regex const expr( "^(\\d{2}):(\\d{2})\\.(\\d{2})$" ) ;
(at the start of the function, before the if).
This would, of course, be better from a technical point of view
but it costs one additional line ;-) But if you are paid for
LOCaday ...

Regards & thanks

M.
Closed Thread