sscanf style string parsing

M

Markus Ilmola

How to a parse a string using C++ (standard library) same way as sscanf
in C.

For example if a have a string:

My name is "John Smith" and I'm 13 years old and 120 cm tall.

and a want to parse the name (string that can be empty (whitout the
quotation marks)), age (unsigned int) and height (unsigned int).

Using plain C I could write something like this:

char name[64];
unsigned int age, height;
sscanf(buffer, "My name is \"%[^\"]\" and I'm %u years old and %u cm
tall.");

However I want to use C++ (standard library) and I need to read the name
to a std::string (buffer is also std::string).
 
N

Noah Roberts

Markus said:
How to a parse a string using C++ (standard library) same way as sscanf
in C.

For example if a have a string:

My name is "John Smith" and I'm 13 years old and 120 cm tall.

and a want to parse the name (string that can be empty (whitout the
quotation marks)), age (unsigned int) and height (unsigned int).

Using plain C I could write something like this:

char name[64];
unsigned int age, height;
sscanf(buffer, "My name is \"%[^\"]\" and I'm %u years old and %u cm
tall.");

You would check for the existance of "My name is \"". Then you would
pass the rest into an istringstream and try to read an int. etc,
etc...

Or you can use something much more powerful like spirit.

You forgot to provide all the args to sscanf btw.
 
D

Daniel T.

Markus Ilmola said:
How to a parse a string using C++ (standard library) same way as sscanf
in C.

For example if a have a string:

My name is "John Smith" and I'm 13 years old and 120 cm tall.

and a want to parse the name (string that can be empty (whitout the
quotation marks)), age (unsigned int) and height (unsigned int).

Using plain C I could write something like this:

char name[64];
unsigned int age, height;
sscanf(buffer, "My name is \"%[^\"]\" and I'm %u years old and %u cm
tall.");

However I want to use C++ (standard library) and I need to read the name
to a std::string (buffer is also std::string).

The following causes my compiler to barf:

int main()
{
char buffer[] = "My name is \"John Smith\" and I'm 13 years old and
120 cm tall.";
char name[64];
unsigned int age, height;
sscanf(buffer, "My name is \"%[^\"]\" and I'm %u years old and %u cm
tall.", name, age, height);
}

Are you sure you can do that with sscanf?

I'd say the easiest way to do it in C++ would be something like this:

void fn( istream& is, string& name, int& age, int& height )
{
find( istream_iterator<char>( is ), istream_iterator<char>(), '\"' );
getline( is, name, '\"' );
find( istream_iterator<string>( is ), istream_iterator<string>(),
"I'm" );
is >> age;
find( istream_iterator<string>( is ), istream_iterator<string>(),
"and" );
is >> height;
}
 
M

Micah Cowan

Daniel T. said:
The following causes my compiler to barf:

int main()
{
char buffer[] = "My name is \"John Smith\" and I'm 13 years old and
120 cm tall.";
char name[64];
unsigned int age, height;
sscanf(buffer, "My name is \"%[^\"]\" and I'm %u years old and %u cm
tall.", name, age, height);
}

Probably because you forgot the & before age and before height.
 
V

Victor Bazarov

Micah said:
Daniel T. said:
The following causes my compiler to barf:

int main()
{
char buffer[] = "My name is \"John Smith\" and I'm 13 years old
and 120 cm tall.";
char name[64];
unsigned int age, height;
sscanf(buffer, "My name is \"%[^\"]\" and I'm %u years old and %u
cm tall.", name, age, height);
}

Probably because you forgot the & before age and before height.

That wouldn't make the compiler barf. It would cause undefined behaviour.
'sscanf' has ... where the 'age' and 'height' are, and the compiler could
not really care less whether you supply the values or the addresses of
them.

V
 
D

Daniel T.

Micah Cowan said:
Daniel T. said:
The following causes my compiler to barf:

int main()
{
char buffer[] = "My name is \"John Smith\" and I'm 13 years old and
120 cm tall.";
char name[64];
unsigned int age, height;
sscanf(buffer, "My name is \"%[^\"]\" and I'm %u years old and %u cm
tall.", name, age, height);
}

Probably because you forgot the & before age and before height.

Yea, that was pretty stupid of me. Just goes to show how often I use the
c io functions...
 
D

Default User

Victor said:
Micah said:
Daniel T. said:
The following causes my compiler to barf:

int main()
{
char buffer[] = "My name is \"John Smith\" and I'm 13 years old
and 120 cm tall.";
char name[64];
unsigned int age, height;
sscanf(buffer, "My name is \"%[^\"]\" and I'm %u years old and %u
cm tall.", name, age, height);
}

Probably because you forgot the & before age and before height.

That wouldn't make the compiler barf. It would cause undefined
behaviour. 'sscanf' has ... where the 'age' and 'height' are, and
the compiler could not really care less whether you supply the values
or the addresses of them.


Might not care. There's nothing to keep the compiler from analyzing the
arguments to the scanf() family, many do, it's just not required to do
so.

For instance, compiled with gcc and -Wall:
sscf.c: In function `main':
sscf.c:10: warning: format argument is not a pointer (arg 4)
sscf.c:10: warning: format argument is not a pointer (arg 5)



Brian
 

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

No members online now.

Forum statistics

Threads
473,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top