<ctype.h>
In C programming language, <ctype.h> is a header which is part of the C standard library. It gives you functions related to the character type char. Although it does sound like it's something about C types (like short, int, float, double) rather than strictly about char ;)
Usage
Here are the functions you get when you include <ctype.h>
/* Test functions */ int isalnum(int); int isalpha(int); int isascii(int); int iscntrl(int); int isdigit(int); int isgraph(int); int islower(int); int isprint(int); int ispunct(int); int isspace(int); int isupper(int); int isxdigit(int); /* Conversion functions */ int toascii(int); int tolower(int); int toupper(int);
How do you use these? Well, for example, rather than making a letter uppercase with char arithmetic (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c you can write isalpha(c) ? toupper(c) : c. That's much nicer! Wouldn't you agree? You could define these kind of functions yourself too, but it's always better to use something someone else made and avoid NIH syndrome. Unless you're learning, then it's completely fine implementing them yourself!
In fact, here's how implement some of them using C macros:
#define isalnum(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z') || ((c) >= '0' && (c) <= '9')) #define isalpha(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z')) #define isdigit(c) ((c) >= '0' && (c) <= '9') #define islower(c) ((c) >= 'a' && (c) <= 'z') #define isupper(c) ((c) >= 'A' && (c) <= 'Z') #define tolower(c) (((c) >= 'A' && (c) <= 'Z') ? ((c) - 'A' + 'a') : (c)) #define toupper(c) (((c) >= 'a' && (c) <= 'a') ? ((c) - 'a' + 'A') : (c))
Let's see an example:
#include <stdio.h> #include <ctype.h> int main() { int c; while ((c = fgetc(stdin)) != EOF) { if (c >= 'a' && c <= 'z') { putchar(c - 'a' + 'A'); } else if (c >= 'A' && c <= 'Z') { putchar(c - 'A' + 'a'); } } return 0; }
Now let's rewrite that example using <ctype.h> functions.
You'd agree it makes the code cleaner?
#include <stdio.h> #include <ctype.h> int main() { int c; while ((c = fgetc(stdin)) != EOF) { if (islower(c)) { putchar(toupper(c)); } else if (isupper(c)) { putchar(); } } return 0; }
In fact, we could collapse the entire if-statement into a oneliner and it would still be somewhat readable!
isalpha(c) && putchar(islower(c) ? toupper(c) : isupper(c) ? tolower(c) : EOF);
But doing it manually would not be as eye-catchy
(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') && putchar(c >= 'a' && c <= 'z' ? c - 'a' + 'A' : c >= 'A' && c <= 'Z' ? c - 'A' + 'a' : EOF);
Why int?
You may notice <ctype.h> functions take an int as the argument instead of char. Why, if โ as its name suggests โ <ctype.h> header is about char types?
The reason is because int is big enough to capture all values of unsigned char (0-255) + the EOF value (-1). A char or unsigned char are not big enough to contain EOF. fgetc() function returns an int for a similar reason โ to give it the ability to return EOF.
int c; while ((c = fgetc(stdin)) != EOF) { /* ... */ }
The return type is also int because C programming language traditionally doesn't have a bool type.
