Most C text uses char strings. <wchar.h> adds wide characters (wchar_t) and functions parallel to string.h—wcslen instead of strlen, wprintf instead of printf. Wide strings help on Windows and in programs that must handle larger character sets than a single byte allows.
01
wchar_t
Wide type.
02
L"..."
Wide literal.
03
wcslen
Length.
04
wprintf
Wide print.
05
mbstowcs
char → wide.
06
WEOF
Wide EOF.
Fundamentals
Definition and Usage
A wide string is an array of wchar_t ending with a null wide character. The L prefix creates wide literals: L"Hello". Functions mirror narrow string.h names with a w prefix or wcs infix.
wchar.h also converts between multibyte char strings (locale-dependent encoding) and wchar_t strings. Set the locale with setlocale from <locale.h> before conversion when handling non-ASCII text.
💡
Beginner Tip
Character tests like iswalpha live in <wctype.h>, not wchar.h. This page focuses on wide strings and I/O. Many tutorials mix the two headers—include both when you need classification and string functions.
Foundation
📝 Syntax
Include the header:
C
#include <wchar.h>
Types and macros
wchar_t — wide character type (typedef in <stddef.h>)
wint_t — can hold any wchar_t value or WEOF
mbstate_t — conversion state for restartable multibyte functions
WEOF — wide end-of-file indicator
NULL — null pointer constant
Wide string functions (parallel to string.h)
wcslen, wcscpy, wcsncpy, wcscat, wcsncat
wcscmp, wcsncmp, wcschr, wcsstr
wcspbrk, wcstok — tokenization (like strtok)
Conversion and I/O
mbstowcs(dest, src, n) — multibyte char string to wide
wcstombs(dest, src, n) — wide string to multibyte char
L"..." creates a wchar_t array. wprintf needs a wide format string and %ls for wide strings. wcstombs fills a narrow buffer for APIs that only accept char*. Check for (size_t)-1 on conversion failure.
Example 2 — wcscpy and wcscat
Build a wide message like strcpy/strcat on narrow strings.
Conversion depends on the current locale. For accented letters like é in “Café”, set an appropriate locale (e.g. setlocale(LC_ALL, "en_US.UTF-8") on Linux). ASCII text works in any locale.
Same rules as strcmp: return 0 when equal. For case-insensitive wide compare, use wcscasecmp (POSIX) or convert with wctype.h functions like towlower.
Applications
🚀 Common Use Cases
Windows APIs — many functions take LPCWSTR wide strings.
Internationalized CLI — messages in multiple scripts via wide I/O.
File paths — Unicode paths on Windows with wide APIs.
Bridging encodings — mbstowcs/wcstombs at system boundaries.
Wide config files — read with fgetws, parse with wcstol.
Localized dates — wcsftime with <time.h>.
🧠 How wchar.h Fits In
1
Choose representation
Narrow char (often UTF-8) or wide wchar_t.
Encoding
2
Use matching API
Wide data → wcs* and wprintf; do not mix blindly.
Consistency
3
Convert at edges
mbstowcs/wcstombs with locale set when needed.
Bridge
=
💬
Multilingual programs
Text beyond ASCII handled through wide or converted paths.
Important
📝 Notes
sizeof(wchar_t) is 2 on many Windows builds, 4 on many Linux builds.
wchar_t encoding is implementation-defined—not a portable Unicode type.
iswalpha/towlower are in <wctype.h>, not wchar.h.
wcstombs/mbstowcs return (size_t)-1 on invalid sequences.
Wide strings must be null-terminated with L'\\0'.
Modern cross-platform code often prefers UTF-8 char strings instead of wchar_t.
Performance
⚡ Optimization
Wide strings use more memory per character than UTF-8 ASCII text. Convert once at boundaries rather than per character in hot loops. If you only need ASCII, narrow strings are simpler and faster. Profile before adopting wide strings throughout a codebase.
Wrap Up
Conclusion
<wchar.h> mirrors <string.h> and <stdio.h> for wide text: wcslen, wcscpy, wprintf, and conversion helpers. Use the L prefix, set locale for conversions, and pair with <wctype.h> for character classification.
For ASCII-only programs, stick to char and string.h. Reach for wchar.h when your platform or API requires wide strings.
Mix printf and wprintf without care on same stream
Ignore buffer sizes on wcscpy/wcscat
Forget null termination after bounded copies
List iswalpha as a wchar.h function in docs
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about wchar.h
Wide characters and strings in C.
5
Core concepts
💬01
wchar_t
Wide char.
Type
📚02
L"..."
Literal.
Prefix
📈03
wcslen
Length.
String
📄04
wprintf
%ls out.
I/O
🌐05
mbstowcs
Convert.
Locale
❓ Frequently Asked Questions
wchar.h is the C standard header for wide characters and wide strings. It declares wchar_t (from stddef.h), wide string functions like wcslen and wcscpy, wide I/O like wprintf, and conversion between multibyte char strings and wchar_t strings with mbstowcs and wcstombs.
char is typically one byte per element for narrow strings (often UTF-8 in modern apps). wchar_t is an integer type wide enough for one wide character—often 2 or 4 bytes depending on platform. Wide literals use the L prefix: L"hello".
L before a character or string literal makes it a wide literal. L'A' has type wchar_t; L"text" is an array of wchar_t ending with L'\0'. Use wide literals with wprintf, wcslen, and other wchar.h functions.
printf writes narrow char strings to stdout. wprintf writes wide strings and uses wide format strings (L"%ls" for wchar_t*). Mixing narrow and wide I/O without conversion causes garbled output or undefined behavior.
wchar.h focuses on wide strings, conversion, and wide I/O (wcscpy, wcslen, mbstowcs, wprintf). wctype.h provides wide character classification and case mapping (iswalpha, towlower). Many programs include both when handling international text.
wchar_t width and encoding are implementation-defined—not portable Unicode. Many new projects use char with UTF-8 instead. wchar.h remains important on Windows APIs and legacy internationalized C code. Know your platform and encoding before choosing.
Did you know?
On Windows, wchar_t is 16 bits and often holds UTF-16 code units. On Linux glibc it is typically 32 bits. The same L"text" source can therefore have different in-memory layout—another reason many portable programs prefer UTF-8 char strings today.