Manipulator for parsing quoted strings

E

erikjalevik

I have a long string of quoted strings, like:

"string 1" "string 2" ...

and I need to split this up into the constituent quoted strings. I was
thinking it would be nice if I could somehow put it in an istringstream
and use operator>> to parse quoted strings instead of
whitespace-separated strings. Would it be at all possible to use a
manipulator for this? So that I could write:

is >> quoted >> s1;
is >> quoted >> s2;

and have s1 contain "string 1" and s2 "string 2". quoted() could easily
be implemented to read everything between the quotes, but I can't see a
way for it to hand over the parsed string to the s1 following it. Is it
possible to do this?

(I don't want to have to subclass string just to override its
operator>>. That seems wrong.)

Thanks,
Erik
 
M

Mike Wahler

I have a long string of quoted strings, like:

"string 1" "string 2" ...

and I need to split this up into the constituent quoted strings. I was
thinking it would be nice if I could somehow put it in an istringstream
and use operator>> to parse quoted strings instead of
whitespace-separated strings. Would it be at all possible to use a
manipulator for this? So that I could write:

is >> quoted >> s1;
is >> quoted >> s2;

and have s1 contain "string 1" and s2 "string 2". quoted() could easily
be implemented to read everything between the quotes, but I can't see a
way for it to hand over the parsed string to the s1 following it. Is it
possible to do this?

(I don't want to have to subclass string just to override its
operator>>. That seems wrong.)

Look up 'std::getline()' (a nonmember function from <string>).
Its last parameter denotes a delimiter you can supply (defaults
to '\n'). You could store each extracted token in e.g. a vector,
then remove any unwanted blank or empty strings (or simply deal
with them as they are created).

-Mike
 
E

erikjalevik

Yep, getline could be used for the job, but I was just curious as to
whether it would be possible to use the extractor syntax for a task
like this. Not because there's no other way of doing it, but just
because I'd really like to do it that way. :)
 
I

int2str

Yep, getline could be used for the job, but I was just curious as to
whether it would be possible to use the extractor syntax for a task
like this. Not because there's no other way of doing it, but just
because I'd really like to do it that way. :)

This is not quite what you wanted, but you could always "fake" the
istream syntax like this:

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

class quoted_extractor
{
public:
quoted_extractor( const std::string & s )
: is_( new std::istringstream(s) )
{
*is_ >> std::noskipws;
}

~quoted_extractor()
{
delete is_;
}

quoted_extractor & operator>> ( std::string & s )
{
char ch;
bool open = false;

s = std::string();

while( !open && *is_ >> ch )
{
if ( ch == '"')
open = true;
}

while( open && *is_ >> ch )
{
if ( ch != '"')
s += ch;
else
open = false;
}

return *this;
}

operator bool() const
{
return is_->good();
}

private:
std::istream *is_;
};


int main()
{
quoted_extractor qs( "\"Hello World\" in german is \"Hallo Welt\"."
);
std::string hello;
while ( qs >> hello )
std::cout << hello << std::endl;
}

Cheers,
Andre
 
E

erikjalevik

Thanks for the in-depth answer, Andre. That does indeed seem like a lot
of trouble to go through just to get to use the >> syntax. At least
this has given me a greater understanding of what manipulators can and
cannot do.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top