wctype.h
isalpha('é') returns 0. The narrow character classification functions in <ctype.h> only handle ASCII (values 0-127); everything else is either wrong or undefined behaviour. wctype.h (C95) is the wide-character counterpart that works on the full Unicode character set via wchar_t values.
#include <wctype.h> #include <locale.h> setlocale(LC_ALL, ""); // needed for correct Unicode classification iswalpha(L'é') // non-zero: é is a letter iswdigit(L'7') // non-zero: decimal digit iswspace(L' ') // non-zero: whitespace iswupper(L'Ä') // non-zero: uppercase letter iswlower(L'ö') // non-zero: lowercase letter iswpunct(L'!') // non-zero: punctuation towupper(L'é') // L'É' towlower(L'Ä') // L'ä'
The functions mirror the <ctype.h> set with an isw prefix instead of is, and tow instead of to. Results are locale-dependent, as in <ctype.h>.
<wctype.h> also provides extensible character class testing via wctype_t:
wctype_t alpha_class = wctype("alpha"); if (iswctype(L'ñ', alpha_class)) wprintf(L"'ñ' is alphabetic\n");
wctrans_t does the same for transformations:
wctrans_t to_upper = wctrans("toupper"); wchar_t result = towctrans(L'é', to_upper); // L'É'
The named character classes recognised by wctype include: alnum, alpha, blank, cntrl, digit, graph, lower, print, punct, space, upper, xdigit. Locale-specific classes may extend this list.
Practice
// compile: gcc -o wcttest wcttest.c // run: ./wcttest // description: classify and case-convert a string of wide characters #include <wctype.h> #include <wchar.h> #include <locale.h> int main(void) { setlocale(LC_ALL, ""); const wchar_t *s = L"héLLo 42!"; for (const wchar_t *p = s; *p; p++) { wprintf(L"'%lc' alpha=%d digit=%d upper=%d upper→%lc\n", *p, iswalpha(*p) != 0, iswdigit(*p) != 0, iswupper(*p) != 0, towupper(*p)); } return 0; }
towupper(L'h') returns L'H'; towupper(L'é') returns L'É' — the accented uppercase form that toupper from <ctype.h> cannot produce. The digit L'4' and punctuation L'!' return themselves unchanged from towupper, as expected.
