Is there a good example of how toupper() works?

Alvin "the Chipmunk" Sylvain asylvain at felix.UUCP
Tue Oct 23 05:26:25 AEST 1990


In article <11021 at hubcap.clemson.edu> svissag at hubcap.clemson.edu
(Steve L Vissage II) writes:
> From article <1990Oct17.170914.683 at wpi.WPI.EDU>, by profesor at wpi.WPI.EDU
> (Matthew E Cross):
> > Nope, won't work - the return value of 'toupper' is undefined if the input
> > is not a lowercase character.
>   
> So define your own toupper() macro.  That's what I did.
> #define toupper(ch) ((ch<123 && ch>96) ? ch-32 : ch)

Two points: first, your macro is *disgustingly unreadable* (and probably
incorrect ...haven't checked).  This is better:

#define toupper(ch) (((ch) >= 'a' && (ch) <= 'z') ? (ch) + 'A' - 'a' : (ch))
#define tolower(ch) (((ch) >= 'A' && (ch) <= 'Z') ? (ch) + 'a' - 'A' : (ch))

Doing it this way, you *almost* know what's going on without comments.
The other way, who the heck knows why you're using 123?   Shouldn't that
be ">= 96", not "> 96"?  I happen to 'remember' that 'a' is 96 in ASCII,
and that the ASCII lower case and upper case are 32 apart ... but I
'forget' whether it's +32 or -32.  My way, I need to remember diddly,
and the compiler handles everything at compile time.  Your way, if I'm
trying to fix or improve your program, how do I know for sure that
you're using 123 and 96 as ASCII characters?

Worse, what happens if we have to port this to (heaven forbid!) EBCDIC?
Those numbers are less than worthless.  (I know, I know, mine is worthless
in EBCDIC also, but that's not the point!  I'll talk about that ...)

Second point: The ANSI standard (refering to _Standard C_ by Plauger & Brodie,
published by Microsoft Press), shows "toupper" and "tolower" as converting
after checking (I.e., it's safe to pass it a non-alpha character).  Power C
(and, I believe others) have a "_toupper" and "_tolower" (with a leading
underscore) which perform the conversion without checking (for speed, when
you're sure of the input).  Defining this macro all over again is unnecessary.

In fact, defining this macro is *dangerous*.  Using a locally defined
"toupper" routine from the standard <ctype.h> *guarantees* that the local
hardware has been taken into account.  Furthermore, this is one more thing
you don't have to debug.  Have you tested that macro over the entire ASCII
character set?  Checked 'a', '`', '@', 'A', 'Z', '[', 'z', '{', etc.?
(boundary checks)

Conclusion: If there is a standard routine that does what you want, *use it*.
This increases reliability and portability and reduces debug time.  If you're
not sure what the routine does, RTFM and/or get help.  If you not sure that
something you want to do has already been done, ask someone.  Good chance
it's already been done.
--
=============Opinions are Mine, typos belong to /bin/ucb/vi=============
"We're sorry, but the reality you have dialed is no   |            Alvin
longer in service.  Please check the value of pi,     |   "the Chipmunk"
or pray to your local deity for assistance."          |          Sylvain
=============================================UUCP: hplabs!felix!asylvain



More information about the Comp.lang.c mailing list