Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Parsing response coming from server

60 views
Skip to first unread message

sumi...@gmail.com

unread,
May 18, 2013, 12:30:00 PM5/18/13
to
I am getting below response from server -

Main stream options:
EncType1=H.264
Resolution1=704*576
KeyInterval1=50
FrameRate1=25
BitflowType1=VBR
NormalBitrate1=2048

Now I need to parse the parameter and its value, I have list of parameter in client, I just need the value of the parameter.

I tried by using string operation and I used -
string::find(), string::substr() and string::find_first_not_of() function
and some how I have complete the code . and its working.

the string for allowed_chars for find_first_not_of() ,
"abcdefghijklmnopqrstuvvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:=-1234567890*"

but its very bulky code and need every time compare with each characters.

please give me some batter idea for parsing .

this should be my function -
string value = getParamValue(const string& response , const string& paramName)
its returns the value of the parameter .

eg.

if I pass "EncType1" function should returns "H.264"

Thanks
Sumit
Message has been deleted

Sam

unread,
May 18, 2013, 5:00:05 PM5/18/13
to
sumi...@gmail.com writes:

> I am getting below response from server -
>
> Main stream options:
> EncType1=H.264
> Resolution1=704*576
> KeyInterval1=50
> FrameRate1=25
> BitflowType1=VBR
> NormalBitrate1=2048
>
> Now I need to parse the parameter and its value, I have list of parameter in
> client, I just need the value of the parameter.
>
> I tried by using string operation and I used -
> string::find(), string::substr() and string::find_first_not_of() function
> and some how I have complete the code . and its working.
>
> the string for allowed_chars for find_first_not_of() ,
> "abcdefghijklmnopqrstuvvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:=-1234567890*"

Irrelevant. All you're looking for is the '='.

> but its very bulky code and need every time compare with each characters.
>
> please give me some batter idea for parsing .

std::istringstream i(response);

std::string line;

while (std::getline(i, line).good())
{
auto b=line.begin(), e=line.end(), p=std::find(b, e, '=');

std::string keyword(b, p); // This is your keyword
if (p != e) ++p;
std::string value(p, e); // This is your value
}

> this should be my function -
> string value = getParamValue(const string& response , const string&
> paramName)
> its returns the value of the parameter .
>
> eg.
>
> if I pass "EncType1" function should returns "H.264"

How to adjust the above code into the calling convention you want is going
to be your homework assignment.

David Harmon

unread,
May 19, 2013, 10:53:19 AM5/19/13
to
On Sat, 18 May 2013 09:30:00 -0700 (PDT) in comp.lang.c++,
sumi...@gmail.com wrote,
>the string for allowed_chars for find_first_not_of() ,
>"abcdefghijklmnopqrstuvvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:=-1234567890*"

I cannot see where that would be at all useful to you. All you are
looking for is the '=' character.

My suggestion is, avoid parsing the string more than once. Parse
the options once and store the results in a std::map where they are
easy to retrieve.

Rui Maciel

unread,
May 19, 2013, 11:30:26 AM5/19/13
to
sumi...@gmail.com wrote:

> Now I need to parse the parameter and its value, I have list of parameter
> in client, I just need the value of the parameter.
>
> I tried by using string operation and I used -
> string::find(), string::substr() and string::find_first_not_of() function
> and some how I have complete the code . and its working.

Why don't you write a proper parser? For that grammar, it's more than
trivial.


Rui Maciel

Jorgen Grahn

unread,
May 19, 2013, 12:08:23 PM5/19/13
to
On Sat, 2013-05-18, Stefan Ram wrote:
> sumi...@gmail.com writes:
>>please give me some batter idea for parsing .
>
> When I am supposed to write a parser, I do
> not want an example of the input language,
> but a grammar of the input language. Usually,
> I cannot derive the grammar from an example.
> so I cannot write a parser from an example.

+1. Also it worries me that it's so common that questions like these
come with only examples. The actual language is an /aid/ to the
programmer, and part of the input requirements. You cannot safely
ignore it.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Rosario1903

unread,
May 19, 2013, 1:15:52 PM5/19/13
to
On Sat, 18 May 2013 09:30:00 -0700 (PDT), wrote:

>the string for allowed_chars for find_first_not_of() ,
>"abcdefghijklmnopqrstuvvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:=-1234567890*"
>
>but its very bulky code and need every time compare with each characters.
>
>please give me some batter idea for parsing .

i would do something as:

#include <iostream>

using namespace std;
#define u8 unsigned char

u8 vect[256];
u8
*avc="abcdefghijklmnopqrstuvvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:=-1234567890*";

void inivect(void)
{unsigned i,c;

for(i=0; i<256; ++i)
vect[i]='?';
for(i=0;avc[i];++i)
vect[avc[i]]=avc[i];
}

#define CharIsOk(x) (vect[x]==(x))
#define safe(x) vect[x]

int main(void)
{unsigned i;
u8 v[]="allow this � ^ bb\n", vv[128], m;

inivect();
cout <<"inizio: "<< v;
for(i=0; v[i]; ++i)
{m=v[i];
if( CharIsOk(m)==0 ) cout << v[i];
vv[i]=safe(m);
}
cout << "not ok\n";
vv[i]=0;
cout <<" fine: "<< vv;
return 0;
}

--------------
inizio: allow this = ^ bb
= ^
not ok
fine: allow?this?????bb?
--------------

Christian Gollwitzer

unread,
May 19, 2013, 1:52:46 PM5/19/13
to
Am 19.05.13 19:15, schrieb Rosario1903:
> On Sat, 18 May 2013 09:30:00 -0700 (PDT), wrote:
> i would do something as:


The below code may work, but it is an awful style
> #include <iostream>
>
> using namespace std;
A matter of debate

> #define u8 unsigned char
Use typedef.

>
> u8 vect[256];
> u8
> *avc="abcdefghijklmnopqrstuvvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:=-1234567890*";
>
> void inivect(void)
> {unsigned i,c;
>
> for(i=0; i<256; ++i)
> vect[i]='?';
> for(i=0;avc[i];++i)
> vect[avc[i]]=avc[i];
> }
>
> #define CharIsOk(x) (vect[x]==(x))
> #define safe(x) vect[x]
Use inline functions.

>
> int main(void)
> {unsigned i;
> u8 v[]="allow this � ^ bb\n", vv[128], m;
>
> inivect();
> cout <<"inizio: "<< v;
> for(i=0; v[i]; ++i)
> {m=v[i];
> if( CharIsOk(m)==0 ) cout << v[i];
> vv[i]=safe(m);
> }
> cout << "not ok\n";
> vv[i]=0;
> cout <<" fine: "<< vv;
> return 0;
> }
>
> --------------
> inizio: allow this = ^ bb
> = ^
> not ok
> fine: allow?this?????bb?
> --------------


>> this should be my function -
>> string value = getParamValue(const string& response , const string& paramName)
>> its returns the value of the parameter
>> if I pass "EncType1" function should returns "H.264"

As others have said, parse the full thing first into a std::map, then
check the map.

Christian

Luca Risolia

unread,
May 19, 2013, 2:28:39 PM5/19/13
to
sumi...@gmail.com wrote:

> I am getting below response from server -
>
> Main stream options:
> EncType1=H.264
> Resolution1=704*576
> KeyInterval1=50
> FrameRate1=25
> BitflowType1=VBR
> NormalBitrate1=2048
>
> Now I need to parse the parameter and its value, I have list of parameter in
> client, I just need the value of the parameter.

> please give me some batter idea for parsing .

#include <iostream>
#include <string>
#include <unordered_map>
#include <boost/regex.hpp>

using Map = std::unordered_map<std::string, std::string>;

Map parse(const std::string& response) {
static const boost::regex expr("(\\w+)=([^\n]*)");
boost::sregex_token_iterator i{response.begin(),
response.end(),
expr,
{1, 2}},
end;
Map m;
for (; i != end; ++i) {
auto& key = *i++, &value = *i;
m.emplace(key, value);
}
return m;
}

int main() {
std::string response =
R"(Main stream options:
EncType1=H.264
Resolution1=704*576
Resolution1=704*577
KeyInterval1=50
FrameRate1=25
BitflowType1=VBR
NormalBitrate1=2048)";

auto m = parse(response);

std::cout << m.at("EncType1");
}

Rosario1903

unread,
May 19, 2013, 2:30:02 PM5/19/13
to
On Sun, 19 May 2013 19:15:52 +0200, Rosario1903
<Ros...@invalid.invalid> wrote:

>i would do something as:
>
>#include <iostream>
>
>using namespace std;
>#define u8 unsigned char
>
>u8 vect[256];
>u8
>*avc="abcdefghijklmnopqrstuvvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:=-1234567890*";
>
>void inivect(void)
>{unsigned i,c;
>
> for(i=0; i<256; ++i)
> vect[i]='?';
> for(i=0;avc[i];++i)
> vect[avc[i]]=avc[i];
>}
>
>#define CharIsOk(x) (vect[x]==(x))

#define CharIsOk(x) (vect[x]==(x)&& (x)!='?')

Jorgen Grahn

unread,
May 19, 2013, 2:34:54 PM5/19/13
to
On Sat, 2013-05-18, sumi...@gmail.com wrote:
> I am getting below response from server -
>
> Main stream options:
> EncType1=H.264
> Resolution1=704*576
> KeyInterval1=50
> FrameRate1=25
> BitflowType1=VBR
> NormalBitrate1=2048

Lets assume for a moment the simplest possible grammar: the language
is a set of lines ended by CRLF. Each line is on the form
"foo=bar\r\n" with no whitespace anywhere. There are no "continuation
lines" like in HTTP or mail headers.

> Now I need to parse the parameter and its value, I have list of
> parameter in client, I just need the value of the parameter.
>
> I tried by using string operation and I used -
> string::find(), string::substr() and string::find_first_not_of() function
> and some how I have complete the code . and its working.

Note that the functions in <algorithm> are at least as useful as the
std::string member functions (which I find a bit hard to work with).
Also there's the stuff in <cctype>.

> the string for allowed_chars for find_first_not_of() ,
> "abcdefghijklmnopqrstuvvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:=-1234567890*"
>
> but its very bulky code and need every time compare with each characters.
>
> please give me some batter idea for parsing .
>
> this should be my function -
> string value = getParamValue(const string& response,
> const string& paramName)

That interface says a few interesting things:

- You are not interested in the difference between "EncType1 isn't
mentioned in the response" and "EncType1 has an empty value".
- You're not interested in the same parameter name being listed twice.
- You have to start from scratch every time you get() a value -- the
work isn't split into one parsing step and one get(name) step. That
means less-than-optimal performance, but perhaps that doesn't
matter.
- You have some way to get the parameters, and nothing but the
parameters, into a single string. I often find that this part is a
bit inconvenient; better to parse line by line into some data
structure until you find end-of-parameters.

Rosario1903

unread,
May 20, 2013, 3:47:43 AM5/20/13
to
On Sat, 18 May 2013 09:30:00 -0700 (PDT), sumit369 wrote:
>I am getting below response from server -
>
>Main stream options:
>EncType1=H.264
>Resolution1=704*576
>KeyInterval1=50
>FrameRate1=25
>BitflowType1=VBR
>NormalBitrate1=2048

i would write global struct one for each names EncType1, Resolution1
etc that contain one unsigned for optuion

than i would do one lookup table from words as "EncType1=" etc that
has as result the right address of the global struct above
than i would parse afther "=" and fill the struct of the type

James Kanze

unread,
May 20, 2013, 9:33:18 AM5/20/13
to
On Saturday, May 18, 2013 10:00:05 PM UTC+1, Sam wrote:
> sumi...@gmail.com writes:

[...]
> std::istringstream i(response);
> std::string line;
> while (std::getline(i, line).good())

The above line is wrong. The use of `std::istream::good()`
means that you're no longer sure when the loop will terminate.
(In particular, it will probably not handle the last line
correctly if it is missing a final '\n'.)

--
James
0 new messages