[comp.lang.c] Another pitfall. Signed chars and ctype.h.

flee@shire.cs.psu.edu (Felix Lee) (02/08/90)

If you have "char * s;" you cannot say something like "isdigit(*s)" if
you want to be 8-bit clean.  "isdigit" etc. take an (int) in the range
[-1, UCHAR_MAX].

You have to say "isdigit((unsigned char) *s)".  Or you could declare
"unsigned char * s;" instead, but this is inconvenient since (char *)
isn't compatible with (unsigned char *).

This is only if your (char) is signed, but if you want to write
portably you shouldn't assume unsignedness of (char).
--
Felix Lee	flee@shire.cs.psu.edu	*!psuvax1!flee

john@frog.UUCP (John Woods) (02/09/90)

In article <Chsv$q2@cs.psu.edu>, flee@shire.cs.psu.edu (Felix Lee) writes:
> If you have "char * s;" you cannot say something like "isdigit(*s)" if
> you want to be 8-bit clean.  "isdigit" etc. take an (int) in the range
> [-1, UCHAR_MAX].
> You have to say "isdigit((unsigned char) *s)".

You have ahold of the wrong end of the stick.

You have to say

	isascii(*s) && isdigit(*s)

isdigit() and friends are all only defined on those values for which
isascii() is true.  If your vendor declares that isascii((char)0x85) is
true, then isdigit((char)0x85) better be made to work, one way or another.
-- 
John Woods, Charles River Data Systems, Framingham MA, (508) 626-1101
...!decvax!frog!john, john@frog.UUCP, ...!mit-eddie!jfw, jfw@eddie.mit.edu

flee@shire.cs.psu.edu (Felix Lee) (02/10/90)

John Woods <john@frog.UUCP> wrote:
> You have to say
>	isascii(*s) && isdigit(*s)

According to _Standard C_ by Plauger and Brodie (the best reference I
have), there is no "isascii".  And "isdigit" etc. take an int in the
set (EOF, 0..UCHAR_MAX), e.g., the possible return values of fgetc().

So, to write ANSI conformant C you must always say something like
	isdigit((unsigned char) *s)
--
Felix Lee	flee@shire.cs.psu.edu	*!psuvax1!flee

henry@utzoo.uucp (Henry Spencer) (02/11/90)

In article <11957@frog.UUCP> john@frog.UUCP (John Woods) writes:
>You have to say
>
>	isascii(*s) && isdigit(*s)
>
>isdigit() and friends are all only defined on those values for which
>isascii() is true...

This is the K&R1 situation.  Unfortunately, the ANSI C situation is as
Felix represented it:  isdigit() is required to work on all unsigned chars
plus EOF.  Trying to build code that will work in both of these environments
is a real headache.
-- 
SVR4:  every feature you ever |     Henry Spencer at U of Toronto Zoology
wanted, and plenty you didn't.| uunet!attcan!utzoo!henry henry@zoo.toronto.edu