sscanf always generates error condition

Greg Hunt hunt at dg-rtp.rtp.dg.com
Wed May 1 12:43:57 AEST 1991


In article <1991Apr30.233554.1321 at agate.berkeley.edu>, ilan343 at violet.berkeley.edu (Geraldo Veiga) writes:
> Is there a good reason why "sscanf" under ISC 2.2 always sets
> "errno=9" even though it executed successfully?
> 
> This is an example:
> 
> #include <stdio.h>
> extern int errno;
> char s[] = "10000";
> main ()
> {
> int tmp;
> sscanf(s,"%d",&tmp);
> perror("System error");
> }
> 
> This is the output of the above code:
> 
> 	System error: Bad file number
> 	(This message corresponds to errno=9)
> 
> If this a bug?  BSD's sscanf doesn't display this behavior.

Yup, it's a bug.  But it's a bug in your code, not sscanf.

Errno is not set on successful conclusion of calls, only on ones that
encountered an error.  So, before looking at errno, you have to check
the return value from whatever you were doing to determine if an error
occurred.  On system calls, the return value for success is usually
zero, and the return value for failure is usually -1.  You have to
read the man page for the calls, though, because some return other
things on success in particular (as is true for sscanf).

Since your example discards the return value from sscanf, you can't
test it to see if some error occurred before you look at errno.  In
the test case, errno is being used without having a value assigned to
it, so the "9" is just garbage that happened to be in the memory
associated with errno at the time.  On the other system you tried, the
garbage happened to have been zero, so everything worked.

You can see that this is what is happening by adding a line like
"errno = 25;" right before sscanf.  Then the "error" you'll get will
be "Not a typewriter"!  This will prove that sscanf is not setting
errno on a successful conclusion.

Take a closer look at the man page for sscanf, particularly the parts
describing the return value.  You'll need to change your code to
capture the return value in a variable, and then test it to see if
an error occurred.  If so, then call perror.  Don't call it otherwise.

This is a pretty common mistake to make, so don't feel bad about it.
It's not intuitive, is it?  You'd think that errno would be set to
zero if the call works, but that's not done for performance reasons.
The return value from calls is always set properly when they return,
and that is what you have to test first to see if an error occurred.

Also take a look at the man page on errno, or perror, for more info
on how errno is handled.

Good luck!

-- 
Greg Hunt                        Internet: hunt at dg-rtp.rtp.dg.com
DG/UX Kernel Development         UUCP:     {world}!mcnc!rti!dg-rtp!hunt
Data General Corporation
Research Triangle Park, NC, USA  These opinions are mine, not DG's.



More information about the Comp.unix.programmer mailing list