Parsing a simple string

M

mathieu

Hello,

I am trying to parse a string and I am surprised by the result(*)
When using:
sscanf(s, "%03u%c", &val, &f);
If a number less than 3 digits is found, shouldn't sscanf report
that ?

Thanks
Mathieu


(*)
#include <stdio.h>

void parse(const char *s)
{
unsigned int val;
char f;
int k = sscanf(s, "%03u%c", &val, &f);
printf( "%d %u %c\n", k, val, f);
}

int main()
{
// 21 years:
parse( "021Y" );
// -1 year (invalid)
parse( "0-1Y" );

return 0;
}
 
R

Robert Gamble

mathieu said:
Hello,

I am trying to parse a string and I am surprised by the result(*)
When using:
sscanf(s, "%03u%c", &val, &f);
If a number less than 3 digits is found, shouldn't sscanf report
that ?

scanf conversion specifiers are not the same as printf's. The %03u
obviously doesn't do what you think it does. The 0 is superfluous and
the 3 just indicates that the *maximum* number of characters to be read
(after skipping any leading whitespace) for that conversion is 3.
Check your documentation for details.

Robert Gamble
 
M

mathieu

Oooops I missed the 'maximum'. Thanks for the info.
I guess I simply make sure that all of the three first char are
decimal.

Mathieu
 
M

mathieu

Just for ref. Here is the final solution:

void parse(const char *s)
{
unsigned int val;
char f;
if( !isdigit(s[0])
|| !isdigit(s[1])
|| !isdigit(s[2]))
{
printf( "error\n");
}
else
{
int k = sscanf(s, "%03u%c", &val, &f);
printf( "%d %u %c\n", k, val, f);
}
}
 
E

Eric Sosman

mathieu wrote On 05/09/06 16:03,:
Just for ref. Here is the final solution:

void parse(const char *s)
{
unsigned int val;
char f;
if( !isdigit(s[0])
|| !isdigit(s[1])
|| !isdigit(s[2]))
{
printf( "error\n");
}
else
{
int k = sscanf(s, "%03u%c", &val, &f);
printf( "%d %u %c\n", k, val, f);
}
}

Just for reference, the above code still has an
error that can cause trouble on some systems. The
problem is that `char' can be a signed type or an
unsigned type, whichever the implementation finds
more convenient. On systems where `char' is signed,
it could happen that any or all of s[0] through s[2]
might have negative values. However, isdigit() only
works on non-negative `char' values and on the negative
value EOF; feed it some other negative value, and
unpredictable things will happen. (True, the digits
are known to have positive values -- but if you knew in
advance that you were dealing with digits, you wouldn't
need the isdigit() calls in the first place!)

Fortunately, the cure (for isdigit() and for the
rest of the <ctype.h> functions) is simple: When you
apply one of them to a `char' value, just convert the
`char' to the corresponding non-negative value:

if ( !isdigit( (unsigned char)s[0] ) ...

Note the part about applying the functions to a
`char'. If you apply them to the `int' value returned
by getchar() or getc() or fgetc(), you should not convert
as shown: the value is already either a converted non-
negative character or else it is the negative number EOF.
If it is EOF, you don't want to convert it from negative
to positive; you want to leave it alone. And if it's not
EOF, it's already non-negative and needs no conversion.
But when you're plucking character values from a string
or something, you need the sign conversion.
 
A

attn.steven.kuo

mathieu said:
Just for ref. Here is the final solution:

void parse(const char *s)
{
unsigned int val;
char f;
if( !isdigit(s[0])
|| !isdigit(s[1])
|| !isdigit(s[2]))
{
printf( "error\n");
}
else
{
int k = sscanf(s, "%03u%c", &val, &f);
printf( "%d %u %c\n", k, val, f);
}
}

With a sscanf format of "%u", leading white space in the input
string, if present, is skipped during conversion. You may want to
consider the possibility of white space being in your input string.
In such a case, a function like this may be useful:

#include <string.h>

size_t count_digits_after_ws (const char *s)
{
const char *ptr = s;
size_t offset = strspn(ptr, " \n\t\r\f\v");
ptr += offset;
offset = strspn(ptr, "0123456789");
return offset;
}
 
M

mathieu

I am saying that:

if( s[0] < '0' || s[0] > '9'
|| s[1] < '0' || s[1] > '9'
|| s[2] < '0' || s[2] > '9' )
{

is equivalent to my previous post with the call of isdigit. But as far
as understand it should not suffer from the unsigned char cast, right ?
 
K

Keith Thompson

mathieu said:
I am saying that:

if( s[0] < '0' || s[0] > '9'
|| s[1] < '0' || s[1] > '9'
|| s[2] < '0' || s[2] > '9' )
{

is equivalent to my previous post with the call of isdigit. But as far
as understand it should not suffer from the unsigned char cast, right ?

I have no idea, since you didn't include any information from your
previous post.

Read <http://cfaj.freeshell.org/google/>.
 
P

pete

mathieu said:
I am saying that:

if( s[0] < '0' || s[0] > '9'
|| s[1] < '0' || s[1] > '9'
|| s[2] < '0' || s[2] > '9' )
{

is equivalent to my previous post with the call of isdigit. But as far
as understand it should not suffer from the unsigned char cast,
right ?

Right.
 
R

Richard Bos

mathieu said:
I am saying that:

if( s[0] < '0' || s[0] > '9'
|| s[1] < '0' || s[1] > '9'
|| s[2] < '0' || s[2] > '9' )
{

is equivalent to my previous post with the call of isdigit. But as far
as understand it should not suffer from the unsigned char cast, right ?

There is no unsigned char cast in that code, so no, it doesn't suffer
from any unsigned char casts.

Richard
 
F

Flash Gordon

mathieu said:
Sorry for that.

Sorry for what? Provide context please when quoting. There are links at
http://clc-wiki.net/wiki/Intro_to_clc to sites with instructions.
> I'll keep that in mind. I did vote for the feature
request at:

http://groups-beta.google.com/support/bin/request.py?contact_type=features

Vote for which feature? Google being separated from Usenet so we don't
get all these context-less posts?
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
 
M

mathieu

Vote for which feature? Google being separated from Usenet so we don't
get all these context-less posts?

Ok I said, I apologized.
What do you do when you only have read access to the newsgroups,
google.groups is very convenient solution, not perfect yet, that's all.
 
K

Keith Thompson

mathieu said:
Sorry for that. I'll keep that in mind. I did vote for the feature
request at:

http://groups-beta.google.com/support/bin/request.py?contact_type=features

I *think* you're saying you voted for the "Default quoting of previous
message in replies" feature. Thanks for that, but it's ironic that
you mention this while not using the simple workaround that lets you
do this in spite of Google's broken interface. (And in a later
followup in this thread, you quote a previous article but snip the
attribution line.)

You *have* read <http://cfaj.freeshell.org/google/>, right?
 
S

SM Ryan

And incessant whining about Google has what to do with
the programming language C?


# mathieu wrote:
# > Sorry for that.
#
# Sorry for what? Provide context please when quoting. There are links at
# http://clc-wiki.net/wiki/Intro_to_clc to sites with instructions.
#
# > I'll keep that in mind. I did vote for the feature
# > request at:
# >
# > http://groups-beta.google.com/support/bin/request.py?contact_type=features
#
# Vote for which feature? Google being separated from Usenet so we don't
# get all these context-less posts?
# --
# Flash Gordon, living in interesting times.
# Web site - http://home.flash-gordon.me.uk/
# comp.lang.c posting guidelines and intro:
# http://clc-wiki.net/wiki/Intro_to_clc
#
# Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
#
#
 
K

Keith Thompson

SM Ryan said:
And incessant whining about Google has what to do with
the programming language C?

It makes it possible to discuss it coherently.

I see you've decided to start top-posting. I can't say I'm surprised.
 
D

Default User

Keith said:
It makes it possible to discuss it coherently.

I see you've decided to start top-posting. I can't say I'm surprised.

Trolls tend to degenerate as their current bag o' tricks gets stale. I
killfiled him long ago over past antics.



Brian
 
M

mathieu

Keith said:
I *think* you're saying you voted for the "Default quoting of previous
message in replies" feature. Thanks for that, but it's ironic that
you mention this while not using the simple workaround that lets you
do this in spite of Google's broken interface. (And in a later
followup in this thread, you quote a previous article but snip the
attribution line.)

I'll make sure to keep attribution line, too. Thx

-M
 

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

Similar Threads

Fibonacci 0
Command Line Arguments 0
Parsing a string 44
Simple sscanf parsing problem 4
String parsing program 25
My Status, Ciphertext 2
string to int 5
out-of-range parsing with <istream> 0

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top