Reference: ctype.h
Testing and converting single characters.
3 minute read
Big idea
<ctype.h> answers questions about single characters — is it a letter? a digit? a space? — and converts between upper and lower case. It's how you check and clean up text one character at a time.
The rule for every function here
Each one takes an int that must be EOF or a value an unsigned char can hold. Plain char can be negative (for accented or non-English characters), and passing a negative value is undefined behaviour. So when the character comes from a string, cast it:
if (isdigit((unsigned char) s[i])) …
The "is" functions return non-zero for true (not necessarily 1) and 0 for false — test them with if, don't compare them to 1.
Classifying characters
| Function | True for | Example |
|---|---|---|
isalpha(c) | a letter, A–Z or a–z | isalpha('q') |
isdigit(c) | a decimal digit 0–9 | isdigit('7') |
isalnum(c) | a letter or a digit | isalnum('x'), isalnum('3') |
isspace(c) | space, \t, \n, \r, \v, \f | isspace('\n') |
isupper(c) | an uppercase letter | isupper('Q') |
islower(c) | a lowercase letter | islower('q') |
ispunct(c) | printable, but not a letter, digit, or space | ispunct('!') |
isxdigit(c) | a hex digit: 0–9, a–f, A–F | isxdigit('b') |
isprint(c) | printable, including space | isprint(' ') |
iscntrl(c) | a control character like \n or \t | iscntrl('\t') |
Converting case
toupper / tolower
int toupper(int c);
int tolower(int c);
Return the other-case version of a letter; any other character comes back unchanged.
- Gotcha: they return the new character — they don't change anything in place. Write
s[i] = toupper((unsigned char) s[i]);. - Example:
toupper('a')→'A',toupper('3')→'3'
Digit values
ctype.h tells you whether something is a digit; to get its value, subtract '0':
int d = c - '0'; /* '7' - '0' == 7 */
This works because the digits '0' to '9' are always consecutive.
#include <stdio.h>
#include <ctype.h>
int main(void) {
char s[] = "Hello, World 2026!";
int letters = 0, digits = 0, spaces = 0, other = 0;
for (int i = 0; s[i] != '\0'; i++) {
unsigned char c = (unsigned char) s[i];
if (isalpha(c)) letters++;
else if (isdigit(c)) digits++;
else if (isspace(c)) spaces++;
else other++;
}
printf("letters=%d digits=%d spaces=%d other=%d\n", letters, digits, spaces, other);
for (int i = 0; s[i] != '\0'; i++) {
s[i] = (char) toupper((unsigned char) s[i]);
}
printf("%s\n", s);
int value = 0;
const char *num = "4096";
for (int i = 0; isdigit((unsigned char) num[i]); i++) {
value = value * 10 + (num[i] - '0');
}
printf("%d\n", value + 1);
return 0;
}output
letters=10 digits=4 spaces=2 other=2
HELLO, WORLD 2026!
4097Run and edit it in the app.
After char c = 'b'; toupper(c); what is c?
Key terms
- Character class — A group like letters, digits, or whitespace.
- Whitespace — Space, tab, newline, and a few other "blank" characters.
- Locale — The language setting that can widen what counts as a letter; by default it's plain English letters.
Check yourself
Why cast to unsigned char before calling isdigit(s[i])?
What is '7' - '0' ?