liveBook · Manning

Wide character

As explained in Modern C

A wide character is a C character representation of type wchar_t intended to encode one character of an extended character set.

Counting characters, not bytes

A separator drawn with multibyte border symbols cannot use strlen to determine its printed character count. Its byte count need not equal its wide-character count, so draw_sep uses the nonstandard mbsrlen instead. section 14.3

A wide character has type wchar_t and represents a character of an extended character set. The C header wchar.h provides wchar_t and conversion utilities. Converting a multibyte string can require an mbstate_t parsing state; mbsrtowcs converts it to wide characters. section 14.3

38   wchar_t* mbsrdup(char const*s, mbstate_t const*restrict state) {
39     size_t mblen = mbsrlen(s, state);
40     if (mblen == -1) return 0;
41     mbstate_t st = state ? *state : *MBSTATE;
42     wchar_t* S = malloc(sizeof(wchar_t[mblen+1]));
43     /* We know that s converts well, so no error check */ 
44     if (S) mbsrtowcs(S, &s, mblen+1, &st);
45     return S;
46   }


!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":0,\"ch\":0},{\"line\":0,\"ch\":2}],[{\"line\":0,\"ch\":5},{\"line\":0,\"ch\":12}],[{\"line\":4,\"ch\":7},{\"line\":4,\"ch\":14}],[{\"line\":0,\"ch\":22},{\"line\":0,\"ch\":32}],[{\"line\":0,\"ch\":36},{\"line\":0,\"ch\":45}],[{\"line\":3,\"ch\":7},{\"line\":3,\"ch\":16}],[{\"line\":0,\"ch\":27},{\"line\":0,\"ch\":32}],[{\"line\":0,\"ch\":52},{\"line\":0,\"ch\":60}],[{\"line\":1,\"ch\":0},{\"line\":1,\"ch\":2}],[{\"line\":1,\"ch\":7},{\"line\":1,\"ch\":13}],[{\"line\":1,\"ch\":14},{\"line\":1,\"ch\":19}],[{\"line\":2,\"ch\":11},{\"line\":2,\"ch\":16}],[{\"line\":4,\"ch\":42},{\"line\":4,\"ch\":47}],[{\"line\":6,\"ch\":31},{\"line\":6,\"ch\":36}],[{\"line\":2,\"ch\":0},{\"line\":2,\"ch\":2}],[{\"line\":2,\"ch\":7},{\"line\":2,\"ch\":9}],[{\"line\":6,\"ch\":7},{\"line\":6,\"ch\":9}],[{\"line\":1,\"ch\":14},{\"line\":1,\"ch\":19}],[{\"line\":2,\"ch\":11},{\"line\":2,\"ch\":16}],[{\"line\":4,\"ch\":42},{\"line\":4,\"ch\":47}],[{\"line\":6,\"ch\":31},{\"line\":6,\"ch\":36}],[{\"line\":2,\"ch\":24},{\"line\":2,\"ch\":30}],[{\"line\":7,\"ch\":7},{\"line\":7,\"ch\":13}],[{\"line\":3,\"ch\":0},{\"line\":3,\"ch\":2}],[{\"line\":0,\"ch\":36},{\"line\":0,\"ch\":45}],[{\"line\":3,\"ch\":7},{\"line\":3,\"ch\":16}],[{\"line\":4,\"ch\":0},{\"line\":4,\"ch\":2}],[{\"line\":0,\"ch\":5},{\"line\":0,\"ch\":12}],[{\"line\":4,\"ch\":7},{\"line\":4,\"ch\":14}],[{\"line\":4,\"ch\":20},{\"line\":4,\"ch\":26}],[{\"line\":4,\"ch\":27},{\"line\":4,\"ch\":33}],[{\"line\":0,\"ch\":5},{\"line\":0,\"ch\":12}],[{\"line\":4,\"ch\":7},{\"line\":4,\"ch\":14}],[{\"line\":1,\"ch\":14},{\"line\":1,\"ch\":19}],[{\"line\":2,\"ch\":11},{\"line\":2,\"ch\":16}],[{\"line\":4,\"ch\":42},{\"line\":4,\"ch\":47}],[{\"line\":6,\"ch\":31},{\"line\":6,\"ch\":36}],[{\"line\":5,\"ch\":0},{\"line\":5,\"ch\":2}],[{\"line\":6,\"ch\":0},{\"line\":6,\"ch\":2}],[{\"line\":2,\"ch\":7},{\"line\":2,\"ch\":9}],[{\"line\":6,\"ch\":7},{\"line\":6,\"ch\":9}],[{\"line\":6,\"ch\":14},{\"line\":6,\"ch\":23}],[{\"line\":1,\"ch\":14},{\"line\":1,\"ch\":19}],[{\"line\":2,\"ch\":11},{\"line\":2,\"ch\":16}],[{\"line\":4,\"ch\":42},{\"line\":4,\"ch\":47}],[{\"line\":6,\"ch\":31},{\"line\":6,\"ch\":36}],[{\"line\":7,\"ch\":0},{\"line\":7,\"ch\":2}],[{\"line\":2,\"ch\":24},{\"line\":2,\"ch\":30}],[{\"line\":7,\"ch\":7},{\"line\":7,\"ch\":13}],[{\"line\":8,\"ch\":0},{\"line\":8,\"ch\":2}]]"}
!@%STYLE%@!

The mbsrdup implementation counts converted characters, allocates space for those wchar_t elements plus a terminator, then calls mbsrtowcs. section 14.3

TAKEAWAY: Do not assume that each char array element is one character. Nor should every wchar_t value be assumed to be a Unicode code point: the example explicitly checks for that implementation property. section 14.3

How Modern C covers it

How deep it goes
Works through conversion and state-aware helper implementations, while deferring broader treatment of wchar_t.
Examples
Shows separator-width calculation, a wide-string duplication helper, and a character-search helper.
What it assumes
Assumes familiarity with char strings and strlen; introduces parsing state where multibyte conversion needs it.
What you can do after
Build it from scratch using mbsrtowcs to allocate and fill a wide-character copy of a multibyte string.
How it connects
Connects wchar_t to multibyte strings, mbstate_t, Unicode, and mbsrtowcs.

Also explained in

Compare how 2 books explain wide character →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern C. The section links point to the parts of the book it draws on.