Ctype Functions: toupper() and tolower()


The easiest way to mess with characters in C is to employ the ctype functions. I name this category of library functions after the ctype.h header file that defines them. Some are true functions, some are macros. Each function can be replicated with standard C code, though it’s quicker to use an established function than to code your own. But that’s not the point of learning to program!

The following code demonstrates the toupper() and tolower() ctype functions. As with all ctype functions, these functions work with with single characters. These two ctype functions are unique, however, in that they return values other than TRUE and FALSE: The toupper() function returns the uppercase character of the argument passed; tolower() returns the lowercase character. These functions have no effect on non-alphabetic characters, returning the character passed as-is.

2026_05_09-Lesson-a.c

#include <stdio.h>
#include <ctype.h>

int main()
{
    char string[] = "Nothing beats knowing the ASCII codes!\n";
    char *s;

    /* uppercase */
    s = string;
    while( *s != '\0' )
    {
        putchar( toupper(*s) );
        s++;
    }

    /* lowercase */
    s = string;
    while( *s != '\0' )
    {
        putchar( tolower(*s) );
        s++;
    }

    return 0;
}

The two while loops output the characters in array string[]. The first loop sends the character through the toupper() function; the second loop sends the character through the tolower() function. Here’s the output:

NOTHING BEATS KNOWING THE ASCII CODES!
nothing beats knowing the ascii codes!

If you’re going to emulate these functions, it helps to know the ASCII code values for letters A through Z. The ASCII table is organized in such a fashion that uppercase and lowercase letters differ by a single bit, as shown in the following table:

A 65 0x41 0100 0001 a 97 0x61 0110 0001
B 66 0x42 0100 0010 b 98 0x62 0110 0010
C 67 0x43 0100 0011 c 99 0x63 0110 0011
D 68 0x44 0100 0100 d 100 0x64 0110 0100
E 69 0x45 0100 0101 e 101 0x65 0110 0101
F 70 0x46 0100 0110 f 102 0x66 0110 0110
G 71 0x47 0100 0111 g 103 0x67 0110 0111
H 72 0x48 0100 1000 h 104 0x68 0110 1000
I 73 0x49 0100 1001 i 105 0x69 0110 1001
J 74 0x4A 0100 1010 j 106 0x6A 0110 1010
K 75 0x4B 0100 1011 k 107 0x6B 0110 1011
L 76 0x4C 0100 1100 l 108 0x6C 0110 1100
M 77 0x4D 0100 1101 m 109 0x6D 0110 1101
N 78 0x4E 0100 1110 n 110 0x6E 0110 1110
O 79 0x4F 0100 1111 o 111 0x6F 0110 1111
P 80 0x50 0101 0000 p 112 0x70 0111 0000
Q 81 0x51 0101 0001 q 113 0x71 0111 0001
R 82 0x52 0101 0010 r 114 0x72 0111 0010
S 83 0x53 0101 0011 s 115 0x73 0111 0011
T 84 0x54 0101 0100 t 116 0x74 0111 0100
U 85 0x55 0101 0101 u 117 0x75 0111 0101
V 86 0x56 0101 0110 v 118 0x76 0111 0110
W 87 0x57 0101 0111 w 119 0x77 0111 0111
X 88 0x58 0101 1000 x 120 0x78 0111 1000
Y 89 0x59 0101 1001 y 121 0x79 0111 1001
Z 90 0x5A 0101 1010 z 122 0x7A 0111 1010

Several clever and fun approaches are available for changing uppercase to lowercase, one of which involves setting or resetting the fifth bit. But for my emulation functions, I use a comparison:

2026_05_09-Lesson-b.c

#include <stdio.h>

/* convert to uppercase */
int toupper(int c)
{
    if( c>='a' && c<='z' )
        c -= 32;

    return(c);
}

/* convert to lowercase */
int tolower(int c)
{
    if( c>='A' && c<='Z' )
        c += 32;

    return(c);
}

int main()
{
    char string[] = "Nothing beats knowing the ASCII codes!\n";
    char *s;

    /* uppercase */
    s = string;
    while( *s != '\0' )
    {
        putchar( toupper(*s) );
        s++;
    }

    /* lowercase */
    s = string;
    while( *s != '\0' )
    {
        putchar( tolower(*s) );
        s++;
    }

    return 0;
}

This update to the code removes including the ctype.h header file. Instead, I wrote my own toupper() and tolower() functions, following the ctype format. Each of my emulations works the same: An if test checks for a letter of the alphabet, upper- or lowercase. If true, the value 32 is subtracted from the character’s value to convert it to uppercase; the value 32 is added to the character’s value to convert it to lowercase. Otherwise, the same character is returned.

The program’s output is the same:

NOTHING BEATS KNOWING THE ASCII CODES!
nothing beats knowing the ascii codes!

In the toupper() function, you could replace the expression c -= 32 with c &= 0xDF By resetting the fifth bit, you convert a lowercase letter to uppercase. Likewise, in the tolower() function you can replace c += 32 with c |=0x20 These modifications work, relying upon bit manipulation to set or reset the bits to make the character conversion. I don’t know which approach is used internally by the C library, though either way works.

Next week I explore the isupper() and islower() functions.

Leave a Reply