# wchar.h If you need to work with non-ASCII text in C — printing accented characters to a terminal, comparing strings that contain Unicode letters, formatting locale-aware dates — you will eventually run into `wchar_t`. **`wchar.h`** (C95) provides wide character I/O and string functions for it: the wide-character mirror of `` and ``, with every function prefixed `w` or `wcs`. ```c #include #include setlocale(LC_ALL, ""); // activate locale for correct output wchar_t *s = L"héllo wörld"; wprintf(L"length: %zu\n", wcslen(s)); // wcslen counts wchar_t units, not bytes // wide string functions mirror their narrow counterparts wcscpy(dst, src) wcscat(dst, src) wcscmp(a, b) wcschr(s, L'é') wcsstr(s, L"sub") ``` The encoding of `wchar_t` is implementation-defined: 32-bit UTF-32 on Linux, 16-bit UTF-16 on Windows. This means `` code is not portable across platforms if it assumes a specific encoding. Wide I/O also comes with a mode restriction: a `FILE` stream switches between narrow and wide mode on first use, and you cannot mix `printf` and `wprintf` on the same stream. `wcsftime` is the wide-character version of `strftime`. `wcstol`, `wcstod`, and similar functions convert wide strings to numbers. `mbsrtowcs` and `wcsrtombs` convert between multibyte (typically UTF-8) and wide strings, using `mbstate_t` to track state across calls: ```c mbstate_t state = {0}; wchar_t wbuf[256]; const char *src = "héllo"; mbsrtowcs(wbuf, &src, 256, &state); ``` For new portable Unicode code, `` (`char16_t`/`char32_t`) is preferable because the encoding is specified. `` is most useful for locale-aware terminal output and for interfacing with system APIs on Linux that use `wchar_t`. ## Practice ```c // compile: gcc -o wcdemo wcdemo.c // run: ./wcdemo // description: print a wide string and its character count vs byte count #include #include #include #include int main(void) { setlocale(LC_ALL, ""); const wchar_t *ws = L"héllo"; const char *ns = "héllo"; // UTF-8: é is 2 bytes wprintf(L"wide string: %ls\n", ws); wprintf(L"wcslen: %zu (wchar_t units)\n", wcslen(ws)); printf( "strlen: %zu (bytes)\n", strlen(ns)); printf( "sizeof wchar_t: %zu\n", sizeof(wchar_t)); return 0; } ``` `wcslen` returns 5 (one unit per character). `strlen` returns 6 because `é` takes two bytes in UTF-8. `sizeof(wchar_t)` is 4 on Linux, so the wide string occupies 20 bytes in memory for five characters — useful to keep in mind when sizing buffers.