C Standard Library wctype.h

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
<wctype.h>

What You’ll Learn

<ctype.h> classifies narrow char values. <wctype.h> does the same for wide characters: iswalpha asks “is this letter?”, towlower changes case. Pair it with <wchar.h> when you process international text with wchar_t strings.

01

iswalpha

Letter?

02

iswdigit

Digit?

03

iswspace

Whitespace?

04

towlower

Lowercase.

05

towupper

Uppercase.

06

wint_t

Arg type.

Definition and Usage

Wide-character classification functions take a wint_t value and return non-zero (true) or zero (false). Conversion functions return the new wide character, or the original if no mapping exists.

Think of wctype.h as the wide mirror of ctype.h: isalphaiswalpha, tolowertowlower. Use them when iterating over wchar_t buffers from wchar.h, not on plain char bytes.

💡
Beginner Tip

For everyday ASCII programs, ctype.h on char is enough. Learn wctype.h when you already use wide strings (L"...", wprintf) or Windows wide APIs.

📝 Syntax

Include the header (usually with wchar.h for wide I/O):

C
#include <wctype.h>
#include <wchar.h>   /* wprintf, wchar_t */

Classification functions

  • iswalpha(wc) — alphabetic letter
  • iswdigit(wc) — decimal digit 0–9
  • iswalnum(wc) — letter or digit
  • iswspace(wc) — whitespace (space, tab, newline, …)
  • iswpunct(wc) — punctuation
  • iswupper(wc) / iswlower(wc) — case tests
  • iswprint(wc) / iswgraph(wc) — printable / visible

Conversion functions

  • towlower(wc) — convert to lowercase wide character
  • towupper(wc) — convert to uppercase wide character

ctype.h vs wctype.h (quick map)

C
isalpha(c)   →  iswalpha(wc)
isdigit(c)   →  iswdigit(wc)
isspace(c)   →  iswspace(wc)
tolower(c)   →  towlower(wc)
toupper(c)   →  towupper(wc)

Headers and linking

  • #include <locale.h> and setlocale(LC_ALL, "") for locale-aware wide rules.
  • Linked automatically with the C library on typical systems.
  • See also ctype.h for narrow characters.

⚡ Quick Reference

FunctionReturns non-zero when
iswalphaWide letter (locale rules)
iswdigitWide digit 09
iswspaceSpace, tab, newline, etc.
iswpunctPunctuation mark
towlowerLowercase mapping (or unchanged)
towupperUppercase mapping (or unchanged)
Letter?
iswalpha(L'Z')

Non-zero

Digit?
iswdigit(L'5')

Non-zero

Lower
towlower(L'A')

L'a'

Upper
towupper(L'b')

L'B'

Examples Gallery

Compile with gcc file.c -std=c11 -o out. Examples use portable ASCII wide letters; extended characters need locale and Unicode terminal support.

📚 Getting Started

Classify and convert a single wide character (fixed from reference).

Example 1 — iswalpha, towlower, towupper

The reference used L'Ä' which often prints ? without locale—this version uses ASCII L'A' for reliable output.

C
#include <stdio.h>
#include <wctype.h>
#include <wchar.h>
#include <locale.h>

int main(void) {
    wint_t wc = L'A';
    wint_t lower;
    wint_t upper;

    setlocale(LC_ALL, "");

    if (iswalpha(wc)) {
        wprintf(L"%lc is an alphabetic character\n", (wchar_t)wc);
    } else {
        wprintf(L"%lc is not alphabetic\n", (wchar_t)wc);
    }

    lower = towlower(wc);
    upper = towupper(lower);

    wprintf(L"Lowercase of %lc is %lc\n", (wchar_t)wc, (wchar_t)lower);
    wprintf(L"Uppercase of %lc is %lc\n", (wchar_t)lower, (wchar_t)upper);

    return 0;
}

How It Works

iswalpha returns non-zero for letters. towlower(L'A') yields L'a'. Arguments are wint_t so EOF from wide input can be distinguished from characters when needed.

Example 2 — iswdigit (Validate a Wide Digit)

Check whether a wide character is 09.

C
#include <stdio.h>
#include <wctype.h>
#include <wchar.h>

int main(void) {
    wchar_t tests[] = { L'0', L'9', L'A', L'-' };
    size_t i;

    for (i = 0; i < 4; i++) {
        wprintf(L"'%lc' -> %s\n", tests[i],
                iswdigit(tests[i]) ? L"digit" : L"not a digit");
    }

    return 0;
}

How It Works

iswdigit is the wide version of isdigit. Use iswalnum when you want letters or digits together.

📈 Practical Patterns

Whitespace, scanning, and case-insensitive compare.

Example 3 — iswspace (Skip Leading Spaces)

Find the first non-whitespace wide character in a string.

C
#include <stdio.h>
#include <wctype.h>
#include <wchar.h>

int main(void) {
    const wchar_t *text = L"   \t Hello";
    const wchar_t *p = text;

    while (iswspace(*p)) {
        p++;
    }

    wprintf(L"Trimmed start: \"%ls\"\n", p);

    return 0;
}

How It Works

iswspace recognizes spaces, tabs, newlines, and other locale-defined whitespace. Do not use isspace on wchar_t values—use the wide function.

Example 4 — Classify Each Character in a Wide String

Count letters, digits, and punctuation in L"Hello, 42!".

C
#include <stdio.h>
#include <wctype.h>
#include <wchar.h>

int main(void) {
    const wchar_t *s = L"Hello, 42!";
    size_t alpha = 0, digit = 0, punct = 0, space = 0;
    const wchar_t *p;

    for (p = s; *p != L'\0'; p++) {
        if (iswalpha(*p)) {
            alpha++;
        } else if (iswdigit(*p)) {
            digit++;
        } else if (iswpunct(*p)) {
            punct++;
        } else if (iswspace(*p)) {
            space++;
        }
    }

    wprintf(L"String: %ls\n", s);
    wprintf(L"Letters: %zu, Digits: %zu, Punct: %zu, Space: %zu\n",
            alpha, digit, punct, space);

    return 0;
}

How It Works

Walk the wide string with a pointer. Categories overlap by design—test in the order that matches your logic (here mutually exclusive branches).

Example 5 — Case-Insensitive Wide Compare

Compare two wide strings letter by letter using towlower.

C
#include <stdio.h>
#include <wctype.h>
#include <wchar.h>

int wide_iequal(const wchar_t *a, const wchar_t *b) {
    while (*a && *b) {
        if (towlower((wint_t)*a) != towlower((wint_t)*b)) {
            return 0;
        }
        a++;
        b++;
    }
    return *a == L'\0' && *b == L'\0';
}

int main(void) {
    const wchar_t *s1 = L"Hello";
    const wchar_t *s2 = L"hELLO";

    if (wide_iequal(s1, s2)) {
        wprintf(L"\"%ls\" equals \"%ls\" (ignore case)\n", s1, s2);
    } else {
        wprintf(L"Strings differ\n");
    }

    return 0;
}

How It Works

POSIX provides wcscasecmp for this; manual towlower loops teach how classification fits with wchar.h string walking. Locale affects non-ASCII letters.

🚀 Common Use Cases

  • Input validation — reject non-digit wide characters in forms.
  • Tokenizers — split wide text on iswspace boundaries.
  • Password rules — require upper, lower, digit with isw* tests.
  • Case-normalizationtowlower before compare or hash.
  • Lexers — classify wide source code characters.
  • Windows UI strings — sanitize wide user input.

🧠 How wctype.h Works

1

Read wchar_t

From a wide string or fgetwc input.

Input
2

Classify or convert

isw* tests category; tow* maps case.

wctype
3

Branch logic

Accept, reject, transform, or count characters.

App code
=

Safe wide parsing

Programs handle international input with explicit rules.

📝 Notes

  • Do not pass char to iswalpha—cast to wchar_t only when the value is a valid wide character.
  • Return value is non-zero for true; compare with if (iswalpha(wc)), not == 1.
  • towlower may return unchanged character if no lowercase exists.
  • Extended Unicode letters need correct locale and wide encoding support.
  • For UTF-8 char text, many apps use ctype.h on bytes only for ASCII, or a Unicode library.
  • Advanced: wctype, iswctype, towctrans for custom locale categories.

⚡ Optimization

Per-character isw* calls in tight loops are usually fine. For ASCII-only data, converting to narrow char and using ctype.h can be faster but only when you know the text is ASCII. Avoid calling setlocale repeatedly inside loops.

Conclusion

<wctype.h> completes the wide-character story started in <wchar.h>. Use iswalpha, iswdigit, and iswspace to inspect characters; use towlower and towupper to normalize case.

You have now covered every standard library header in this tutorial series. Continue with C interview programs or revisit the library index.

💡 Best Practices

✅ Do

  • Pair wctype.h with wchar.h wide strings
  • Call setlocale for non-ASCII wide characters
  • Use isw* on wchar_t, is* on char
  • Test with ASCII examples first, then extend locale
  • Handle towlower returning unchanged chars
  • Link to ctype.h for narrow equivalents

❌ Don’t

  • Use isalpha on wchar_t values
  • Assume L'Ä' works without locale/terminal support
  • Mix narrow and wide classification in one loop blindly
  • Compare iswalpha result to exactly 1
  • Forget that rules change when locale changes
  • List iswalpha under wchar.h in docs

Key Takeaways

Knowledge Unlocked

Five things to remember about wctype.h

Wide ctype—mirror of ctype.h.

5
Core concepts
📚 02

iswdigit

0–9.

Test
📈 03

iswspace

Skip ws.

Parse
📄 04

towlower

Downcase.

Map
🌐 05

ctype.h

Narrow twin.

Pair

❓ Frequently Asked Questions

wctype.h is the C standard header for classifying and converting wide characters. It provides iswalpha, iswdigit, iswspace, towlower, towupper, and related functions—the wide-character equivalents of ctype.h functions like isalpha and tolower.
ctype.h works on narrow characters (char/int) from byte strings. wctype.h works on wide characters (wint_t/wchar_t) from wide strings. Use ctype.h with printf and char*; use wctype.h with wprintf and wchar_t*.
wchar.h handles wide strings and I/O: wcslen, wcscpy, wprintf, mbstowcs. wctype.h tests and transforms single wide characters: iswalpha, towlower. Include wchar.h for string work and wctype.h when you need per-character wide classification.
wint_t is an integer type that can hold any value of wchar_t plus the special value WEOF. Classification functions like iswalpha take wint_t so they can accept wide characters and end-of-file indicators from wide input functions.
Yes. Which characters count as letters, digits, or whitespace depends on the current locale. Call setlocale from locale.h when you need locale-aware behavior—for example handling accented letters in European languages.
The reference used L'Ä' without setlocale and possibly a console that could not display the character. For portable tutorials, start with ASCII wide letters like L'A'. For extended characters, set locale (e.g. en_US.UTF-8) and ensure your terminal supports Unicode.
Did you know?

The C standard names every wide classification function with a leading isw and every wide case conversion with tow (think “to wide”). That naming mirror makes it easy to guess the wide version once you know ctype.h.

Explore C Standard Library Headers

All library tutorials are complete—browse the index or try interview programs.

Standard Library Index →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful