C Standard Library wchar.h

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

What You’ll Learn

Most C text uses char strings. <wchar.h> adds wide characters (wchar_t) and functions parallel to string.hwcslen 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.

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.

📝 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
  • wprintf, fwprintf, swprintf — wide formatted output
  • wscanf, fgetws, fputws — wide input/output
  • wcsftime — wide version of strftime from <time.h>

Typical wide string

C
wchar_t greeting[] = L"Hello";
size_t n = wcslen(greeting);
wprintf(L"Text: %ls (len %zu)\n", greeting, n);

Headers and linking

  • #include <wchar.h> — often needs <stdio.h> for wprintf.
  • #include <locale.h> for setlocale before mbstowcs/wcstombs.
  • Compile: gcc program.c -std=c11 -o program.

⚡ Quick Reference

Narrow (string.h)Wide (wchar.h)Action
strlenwcslenString length
strcpywcscpyCopy string
strcmpwcscmpCompare
printf %swprintf %lsPrint string
mbstowcschar → wchar_t
wcstombswchar_t → char
Literal
L"wide text"

Prefix L

Print
wprintf(L"%ls", s)

Wide fmt

Locale
setlocale(LC_ALL,"")

Before convert

EOF
WEOF

Wide streams

Examples Gallery

Compile with gcc file.c -std=c11 -o program. Wide output may require a terminal that supports Unicode.

📚 Getting Started

Wide strings and conversion from the reference.

Example 1 — wprintf, wcslen, and wcstombs

From the reference: print a wide string, measure it, convert to multibyte for printf.

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

int main(void) {
    wchar_t wstr[] = L"Hello, World!";
    char mbs[64];
    size_t converted;

    setlocale(LC_ALL, "");

    wprintf(L"Wide string: %ls\n", wstr);
    wprintf(L"Length (wcslen): %zu\n", wcslen(wstr));

    converted = wcstombs(mbs, wstr, sizeof(mbs));
    if (converted == (size_t)(-1)) {
        fprintf(stderr, "wcstombs failed\n");
        return 1;
    }
    mbs[converted] = '\0';
    printf("Multibyte string: %s\n", mbs);

    return 0;
}

How It Works

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.

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

int main(void) {
    wchar_t buf[32] = L"Hello, ";
    const wchar_t *name = L"Ada";

    wcscat(buf, name);
    wprintf(L"Greeting: %ls\n", buf);
    wprintf(L"Total length: %zu\n", wcslen(buf));

    return 0;
}

How It Works

wcscat appends at the existing wide null terminator. Buffer must fit both parts plus L'\\0'. Prefer wcsncat or bounded copies in production code.

📈 Practical Patterns

Conversion, comparison, and locale.

Example 3 — mbstowcs (Narrow to Wide)

Read a UTF-8 or locale-encoded char string into wchar_t.

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

int main(void) {
    const char *narrow = "Cafe";
    wchar_t wide[32];
    size_t n;

    setlocale(LC_ALL, "");

    n = mbstowcs(wide, narrow, 32);
    if (n == (size_t)(-1)) {
        fprintf(stderr, "mbstowcs failed\n");
        return 1;
    }
    wide[n] = L'\0';

    wprintf(L"Wide: %ls (%zu chars)\n", wide, wcslen(wide));

    return 0;
}

How It Works

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.

Example 5 — wcscmp (Compare Wide Strings)

Case-sensitive wide string comparison for commands or filenames.

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

int main(void) {
    const wchar_t *cmd = L"quit";
    wchar_t input[16] = L"quit";

    if (wcscmp(input, cmd) == 0) {
        wprintf(L"Command matched: exiting.\n");
    } else if (wcsncmp(input, L"help", 4) == 0) {
        wprintf(L"Help requested.\n");
    } else {
        wprintf(L"Unknown command: %ls\n", input);
    }

    return 0;
}

How It Works

Same rules as strcmp: return 0 when equal. For case-insensitive wide compare, use wcscasecmp (POSIX) or convert with wctype.h functions like towlower.

🚀 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 encodingsmbstowcs/wcstombs at system boundaries.
  • Wide config files — read with fgetws, parse with wcstol.
  • Localized dateswcsftime 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.

📝 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.

⚡ 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.

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.

💡 Best Practices

✅ Do

  • Use L"..." literals with wide functions
  • Call setlocale before locale-sensitive conversion
  • Check mbstowcs/wcstombs for (size_t)-1
  • Size wide buffers for characters + L'\\0'
  • Use %ls in wprintf for wchar_t*
  • Include wctype.h for iswalpha, towlower

❌ Don’t

  • Pass narrow char* to wcslen or wprintf %ls
  • Assume wchar_t is UTF-16 or UTF-32 everywhere
  • 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

Key Takeaways

Knowledge Unlocked

Five things to remember about wchar.h

Wide characters and strings in C.

5
Core concepts
📚 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.

Explore C Standard Library Headers

Continue with wctype.h or browse the library index.

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