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

scanf and input failure

0 views
Skip to first unread message

Noone Really

unread,
Feb 13, 1999, 3:00:00 AM2/13/99
to
Two different compilers (gcc on solaris and linux) produced the same
output with this code, and I believe the output is incorrect (as
clarified in the RRs).

#include <stdio.h>
int main(void) {
static int g,h,i,j,k,l,m,n,p;
printf("%d %d %d %d %d %d\n",
sscanf("","%*d"),
sscanf("123","%*d"),
sscanf("123","%*d%*d"),
sscanf("123","%*d%n%n",&g,&h),
sscanf("123","%*d%n%n%d",&i,&j,&k),
sscanf("123","%d%n%n%d",&l,&m,&n,&p));
printf("%d %d %d %d %d %d %d %d %d\n", g,h,i,j,k,l,m,n,p);
return 0;
}

It produced the following output:

-1 0 -1 0 -1 1
3 3 3 3 0 123 3 3 0

I believe that the second last number on the first line should be 0, not
-1.

To be precise, my reading of the standard was -1 for the last two cases,
and the corresponding 0s instead of 3s. But given that the response to
the defect report (DR 14 was it?) said it was not an input failure (the
example provided in the response was obviously wrong as noted in a much
later response), I cannot see how the second last sscanf can have a
different answer. Especially if i and j are 3. I think the wording in
the current standard is much clearer.

Who is correct? Me or the compilers?
---


Clive D.W. Feather

unread,
Feb 14, 1999, 3:00:00 AM2/14/99
to
In article <36C66051...@earthlink.net>, Noone Really
<nooneat...@earthlink.net> writes

>#include <stdio.h>
>int main(void) {
> static int g,h,i,j,k,l,m,n,p;
> printf("%d %d %d %d %d %d\n",
> sscanf("","%*d"),
> sscanf("123","%*d"),
> sscanf("123","%*d%*d"),
> sscanf("123","%*d%n%n",&g,&h),
> sscanf("123","%*d%n%n%d",&i,&j,&k),
> sscanf("123","%d%n%n%d",&l,&m,&n,&p));
> printf("%d %d %d %d %d %d %d %d %d\n", g,h,i,j,k,l,m,n,p);
> return 0;
>}
>
>It produced the following output:
>
>-1 0 -1 0 -1 1

That appears wrong to me. I would say it should be:

-1 0 0 0 0 1

>3 3 3 3 0 123 3 3 0

Looks right.

>I believe that the second last number on the first line should be 0, not
>-1.

[...]

If %d is offered end-of-input (an empty string in this case) it is an
input failure. This produces EOF as output if it happens before any
conversion, and terminates the operation otherwise.

So all the others *did* a conversion but assigned 0 (or 1 in the last
case) items. Hence the results.

--
Clive D.W. Feather | Director of | Work: <cl...@demon.net>
Tel: +44 181 371 1138 | Software Development | Home: <cl...@davros.org>
Fax: +44 181 371 1037 | Demon Internet Ltd. | Web: <http://www.davros.org>
Written on my laptop; please observe the Reply-To address

Noone Really

unread,
Feb 14, 1999, 3:00:00 AM2/14/99
to
Clive D.W. Feather wrote:
>
> In article <36C66051...@earthlink.net>, Noone Really
> <nooneat...@earthlink.net> writes
> >#include <stdio.h>
> >int main(void) {
> > static int g,h,i,j,k,l,m,n,p;
> > printf("%d %d %d %d %d %d\n",
> > sscanf("","%*d"),
> > sscanf("123","%*d"),
> > sscanf("123","%*d%*d"),
> > sscanf("123","%*d%n%n",&g,&h),
> > sscanf("123","%*d%n%n%d",&i,&j,&k),
> > sscanf("123","%d%n%n%d",&l,&m,&n,&p));
> > printf("%d %d %d %d %d %d %d %d %d\n", g,h,i,j,k,l,m,n,p);
> > return 0;
> >}
> >
> >It produced the following output:
> >
> >-1 0 -1 0 -1 1
>
> That appears wrong to me. I would say it should be:
>
> -1 0 0 0 0 1
^
Now you go ahead and confus me again :-) I would have said that this
should be -1 as the compiler did. (The first %*d succeeded but got an
end of file which terminated the next %*d with an input failure, so the
result is EOF, which happens to be -1 here. Only %n is a special case:
not %*d.)

>
> >3 3 3 3 0 123 3 3 0
>
> Looks right.
>
> >I believe that the second last number on the first line should be 0, not
> >-1.

You seem to agree with me here.

> [...]
>
> If %d is offered end-of-input (an empty string in this case) it is an
> input failure. This produces EOF as output if it happens before any
> conversion, and terminates the operation otherwise.

*and* causes the next directive, if any (and if not %n or its variants),
to get an input failure, if the currrent directive did not have a
matching failure. (Without multibyte characters, I guess the only way
that the current directive can get a matching failure is if the file
ends in something like "123.0e+" and you are reading in something like
"%e" format. Right?)

>
> So all the others *did* a conversion but assigned 0 (or 1 in the last
> case) items. Hence the results.

I do not agree. The second %*d in the third sscanf should have got
input failure because it is the next directive to the first %*d which
detected the end of file. It is immaterial then that the first
conversion succceeded.

Or am I misreading something?
---


James Youngman

unread,
Feb 14, 1999, 3:00:00 AM2/14/99
to
Noone Really <nooneat...@earthlink.net> writes:

> Two different compilers (gcc on solaris and linux) produced the same
> output with this code, and I believe the output is incorrect (as
> clarified in the RRs).
>

> #include <stdio.h>
> int main(void) {
> static int g,h,i,j,k,l,m,n,p;
> printf("%d %d %d %d %d %d\n",
> sscanf("","%*d"),
> sscanf("123","%*d"),
> sscanf("123","%*d%*d"),
> sscanf("123","%*d%n%n",&g,&h),
> sscanf("123","%*d%n%n%d",&i,&j,&k),
> sscanf("123","%d%n%n%d",&l,&m,&n,&p));
> printf("%d %d %d %d %d %d %d %d %d\n", g,h,i,j,k,l,m,n,p);
> return 0;
> }
>
> It produced the following output:
>
> -1 0 -1 0 -1 1

> 3 3 3 3 0 123 3 3 0
>

> I believe that the second last number on the first line should be 0, not
> -1.

This reduces to:-

#include <stdio.h>

int main(void) {
int i,j,k;
int ret;

ret = sscanf("123","%*d%n%n%d",&i,&j,&k);
printf("[%d]\n", ret);
return 0;
}

which emits [-1]. Since the 123 was converted, but simply not
assigned, I would expect a return value of 1 rather than -1 or 0, but
then I don't have the standard document to hand.

If %*d doesn't count as a conversion at all, then -1 would be correct,
I think.

--
ACTUALLY reachable as @free-lunch.demon.(whitehouse)co.uk:james+usenet

Noone Really

unread,
Feb 14, 1999, 3:00:00 AM2/14/99
to
Noone Really wrote:
> > [...]
> >
> > If %d is offered end-of-input (an empty string in this case) it is an
> > input failure. This produces EOF as output if it happens before any
> > conversion, and terminates the operation otherwise.
>
> *and* causes the next directive, if any (and if not %n or its variants),
> to get an input failure, if the currrent directive did not have a
> matching failure. (Without multibyte characters, I guess the only way
> that the current directive can get a matching failure is if the file
> ends in something like "123.0e+" and you are reading in something like
> "%e" format. Right?)
>
> >
> > So all the others *did* a conversion but assigned 0 (or 1 in the last
> > case) items. Hence the results.
>
> I do not agree. The second %*d in the third sscanf should have got
> input failure because it is the next directive to the first %*d which
> detected the end of file. It is immaterial then that the first
> conversion succceeded.
>
> Or am I misreading something?

I apologize for the nonsensical post quoted above.

I obviously was ... rereading the standard, I see that input failure
does not imply a return value of EOF. So, I guess my compilers are
broken much more than I thought they were!

So, what exactly is the point of the standard specifying that the
`execution of the next directive (if any) is terminated with an input
failure'. I mean is that last phrase `with an input failure' of any
use? Would the meaning of the standard be changed if that phrase was
omitted?
---


Noone Really

unread,
Feb 14, 1999, 3:00:00 AM2/14/99
to
James Youngman wrote:
> #include <stdio.h>
>
> int main(void) {
> int i,j,k;
> int ret;
>
> ret = sscanf("123","%*d%n%n%d",&i,&j,&k);
> printf("[%d]\n", ret);
> return 0;
> }
>
> which emits [-1]. Since the 123 was converted, but simply not
> assigned, I would expect a return value of 1 rather than -1 or 0, but
> then I don't have the standard document to hand.

Return value is the number assigned (except %n assignments), not number
converted. It is EOF only if no conversions took place before input
failure.

>
> If %*d doesn't count as a conversion at all, then -1 would be correct,
> I think.

Aha! That must be the point. The standard seems to say that %*d is a
conversion without assignment, whereas all the cases I tried can be
explained if the compiler was assuming that %*d is not a conversion.

This must be the mistake the compiler is making.

Thank you all.
---


Will Rose

unread,
Feb 14, 1999, 3:00:00 AM2/14/99
to
Clive D.W. Feather (cl...@on-the-train.demon.co.uk) wrote:
: In article <36C66051...@earthlink.net>, Noone Really
: <nooneat...@earthlink.net> writes
: >#include <stdio.h>

: >int main(void) {
: > static int g,h,i,j,k,l,m,n,p;
: > printf("%d %d %d %d %d %d\n",
: > sscanf("","%*d"),
: > sscanf("123","%*d"),
: > sscanf("123","%*d%*d"),
: > sscanf("123","%*d%n%n",&g,&h),
: > sscanf("123","%*d%n%n%d",&i,&j,&k),
: > sscanf("123","%d%n%n%d",&l,&m,&n,&p));
: > printf("%d %d %d %d %d %d %d %d %d\n", g,h,i,j,k,l,m,n,p);
: > return 0;
: >}
: >
: >It produced the following output:
: >
: >-1 0 -1 0 -1 1

: That appears wrong to me. I would say it should be:

: -1 0 0 0 0 1

Interesting; there are a lot of broken compilers out there
then, because I get the '-1 0 -1 0 -1 1' result on both of
those I can easily reach.


Will
c...@crash.cts.com


Clive D.W. Feather

unread,
Feb 15, 1999, 3:00:00 AM2/15/99
to
In article <x690e1j...@no-such-thing-as-a.free-lunch.demon.co.uk>,
[...]
>If %*d doesn't count as a conversion at all, then -1 would be correct,
>I think.

I disagree.

As I read it:

input failure before the first successful conversion -> EOF
otherwise return the number of assignments:
- %*d is a conversion but not an assignment
- %d is a conversion and, if it succeeds, an assignment

Clive D.W. Feather

unread,
Feb 15, 1999, 3:00:00 AM2/15/99
to
In article <36C74491...@earthlink.net>, Noone Really
<nooneat...@earthlink.net> writes

>So, what exactly is the point of the standard specifying that the
>`execution of the next directive (if any) is terminated with an input
>failure'. I mean is that last phrase `with an input failure' of any
>use? Would the meaning of the standard be changed if that phrase was
>omitted?

Not directly. However, it makes it easier to describe if all failures
are clearly either input or matching. It also lets you extrapolate the
behaviour of other cases.

0 new messages