[comp.lang.c] toupper

dg@lakart.UUCP (David Goodenough) (01/04/89)

From article <9256@smoke.BRL.MIL>, by gwyn@smoke.BRL.MIL (Doug Gwyn ):
> In article <189@becker.UUCP> bdb@becker.UUCP (Bruce Becker) writes:
>>	It might be useful to add that testing for EOF is
>>	possible - this raises the question of its value.
>>	Ought it to be -1, or 0xFF, or what? I'm confused
>>	about what the value of "toupper(EOF)" should be...
> 
> EOF is not required to be defined as -1, but that is really the
> most practical choice in every environment I've seen.  It must
> NOT be the same as a possible character value, so 0xFF is wrong.
> 
> I don't think EOF is supposed to be a valid argument for toupper(),
> just for the is*() functions.

I don't know about the rest of the world, but there are three classes of
toupper() that I know about.

1. they correctly convert lower case letters, and are undefined for ANY
OTHER VALUES. What this does with EOF will be undefined.

2. they convert lower case to upper, and leave ALL OTHER VALID characters
alone; undefined otherwise. Since EOF (ipso facto) is not a valid character
it is again undefined.

3. they convert lower case to upper and leave EVERYTHING else alone. In this
environment toupper(EOF) == EOF.

However, since portability requires that one assume 1., toupper(EOF) is
non-portable, hence probably best left alone. If you DO want 3. try the
following:

int to_upper(c)
int c;
 {
    return(islower(c) ? toupper(c) : c);
 }
-- 
	dg@lakart.UUCP - David Goodenough		+---+
							| +-+-+
	....... !harvard!xait!lakart!dg			+-+-+ |
AKA:	dg%lakart.uucp@xait.xerox.com		  	  +---+

daveh@marob.masa.com (Dave Hammond) (09/16/89)

In article <9366@attctc.Dallas.TX.US> bobc@attctc.Dallas.TX.US writes:
>[...] I figured that it would have been simpler to do something like
>
>	while (((ch = toupper(getch())) != 'Y') && (ch !='N'));
>

Note that some implementations of toupper() (SunOS comes to mind)
will return the wrong result if passed a non-lowercase argument.
You'd probably want to expand this line and run an islower()
test on the argument to toupper:

	int temp;
	while ( ((ch = (islower(temp=getch())
			? toupper(temp)
			: temp)) != 'Y') && (ch !='N'));

--
Dave Hammond
daveh@marob.masa.com

henry@utzoo.uucp (Henry Spencer) (09/17/89)

In article <2511ADAD.6056@marob.masa.com> daveh@marob.masa.com (Dave Hammond) writes:
>Note that some implementations of toupper() (SunOS comes to mind)
>will return the wrong result if passed a non-lowercase argument.
>You'd probably want to expand this line and run an islower()
>test on the argument to toupper...

It's worse than that.  Some implementations of islower() (e.g. the original
V7 one, still found in many Unixes) cannot safely be applied to any char
value -- you have to precede them with an isascii() test.  This is an awful
nuisance if you're trying to write maximally-portable code, because ANSI C
requires islower() to work on any char and hence does not have isascii()...
-- 
V7 /bin/mail source: 554 lines.|     Henry Spencer at U of Toronto Zoology
1989 X.400 specs: 2200+ pages. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu