iconv(3)

๐Ÿ’ซ iconv(3) โ€” the glow-up where your bytes change outfits ๐Ÿ’ซ

okay bestie, pull up a chair ๐Ÿซถ this is iconv(3) from the Library Functions Manual, living in the Standard C library (libc, -lc). She converts your characters from one encoding to another, and honestly? iconic behaviour. no cap.


๐ŸŒธ NAME ๐ŸŒธ

iconv โ€” perform character set conversion โœจ

๐Ÿ“š LIBRARY ๐Ÿ“š

Standard C library (libc, -lc) ๐Ÿ’–

๐ŸŽ€ SYNOPSIS ๐ŸŽ€

#include <iconv.h>

size_t iconv(iconv_t cd,
             char **restrict inbuf, size_t *restrict inbytesleft,
             char **restrict outbuf, size_t *restrict outbytesleft);

๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

so like, the iconv() function converts a sequence of characters in one character encoding into a sequence of characters in a different character encoding. she's a translator, she's multilingual, she's giving main character energy ๐Ÿ’…

  • cd โ€” the conversion descriptor. this is something you already made by calling iconv_open(3) earlier. it's the one that defines which two encodings iconv() is using for the conversion. no cd, no vibes.
  • inbuf โ€” the address of a variable that points to the first character of the input sequence. yes, address-of-a-pointer, we love a double pointer moment ๐Ÿ™ˆ
  • inbytesleft โ€” how many bytes are chillin' in that input buffer.
  • outbuf โ€” the address of a variable pointing to the first byte available in the output buffer.
  • outbytesleft โ€” how many bytes are available in the output buffer.

โœจ the main case (the one you'll actually use) โœจ

this is when inbuf is not NULL and *inbuf is not NULL. in this case iconv() converts the multibyte sequence starting at *inbuf into a multibyte sequence starting at *outbuf.

  • at most *inbytesleft bytes, starting at *inbuf, will be read ๐Ÿ“–
  • at most *outbytesleft bytes, starting at *outbuf, will be written โœ๏ธ

she converts one multibyte character at a time, and for each character conversion she does the lil bookkeeping dance:

  • increments *inbuf and decrements *inbytesleft by the number of converted input bytes
  • increments *outbuf and decrements *outbytesleft by the number of converted output bytes
  • updates the conversion state contained inside cd

and here's a fun one: if the input's character encoding is stateful, iconv() can also convert a sequence of input bytes into an update to the conversion state without producing any output bytes at all. that kind of input is called a shift sequence. sneaky. love that for her.

the conversion can stop for five reasons, and bestie you gotta know all five:

  • ๐Ÿ˜ญ an invalid multibyte sequence shows up in the input. she sets errno to EILSEQ and returns (size_t) -1. *inbuf is left pointing at the beginning of the invalid multibyte sequence.
  • ๐Ÿ˜ญ a multibyte sequence shows up that's valid but can't be translated into the output's character encoding. this one depends on the implementation and on the conversion descriptor. in the GNU C library and GNU libiconv, if cd was created without the suffix //TRANSLIT or //IGNORE, the conversion is strict: lossy conversions produce this condition. if the suffix //TRANSLIT was specified, transliteration can avoid this condition in some cases. in the musl C library, this condition can't occur at all, because a conversion to '*' is used as a fallback. in the FreeBSD, NetBSD, and Solaris implementations of iconv(), this condition can't occur either, because a conversion to '?' is used as a fallback. when this condition is met, iconv() sets errno to EILSEQ and returns (size_t) -1. *inbuf is left pointing at the beginning of the unconvertible multibyte sequence.
  • โœ… the input byte sequence has been entirely converted, i.e. *inbytesleft has gone down to 0. in this case iconv() returns the number of nonreversible conversions performed during this call. slay.
  • ๐Ÿ˜ญ an incomplete multibyte sequence shows up in the input, and the input byte sequence terminates right after it. she sets errno to EINVAL and returns (size_t) -1. *inbuf is left pointing at the beginning of the incomplete multibyte sequence.
  • ๐Ÿ˜ญ the output buffer has no more room for the next converted character. she sets errno to E2BIG and returns (size_t) -1.

๐ŸŒ€ the second case (the reset/flush moment) ๐ŸŒ€

different scenario: inbuf is NULL or *inbuf is NULL, but outbuf is not NULL and *outbuf is not NULL.

here, iconv() tries to set cd's conversion state back to the initial state and store a corresponding shift sequence at *outbuf. at most *outbytesleft bytes, starting at *outbuf, will be written.

if the output buffer has no more room for this reset sequence, she sets errno to E2BIG and returns (size_t) -1. otherwise she increments *outbuf and decrements *outbytesleft by the number of bytes written. โœจ clean slate energy โœจ

๐Ÿง˜ the third case (the quiet one) ๐Ÿง˜

third case: inbuf is NULL or *inbuf is NULL, and outbuf is NULL or *outbuf is NULL.

in this case iconv() just sets cd's conversion state to the initial state. that's it. no output, no drama, just vibes.


๐Ÿ”ฅ RETURN VALUE ๐Ÿ”ฅ

iconv() returns the number of characters converted in a nonreversible way during this call โ€” reversible conversions don't get counted, they're just out here living rent-free ๐Ÿ˜Œ

in case of error, iconv() returns (size_t) -1 and sets errno to indicate the error.


๐Ÿ’€ ERRORS ๐Ÿ’€

the following errors can occur, among others (so this is not an exhaustive list, okay?):

  • E2BIG โ€” there isn't sufficient room at *outbuf. your output buffer said "no more room bestie" ๐Ÿšซ
  • EILSEQ โ€” an invalid multibyte sequence has been encountered in the input.
  • EINVAL โ€” an incomplete multibyte sequence has been encountered in the input.

๐Ÿ‘‘ ATTRIBUTES ๐Ÿ‘‘

for an explanation of the terms used in this section, see attributes(7).

  • Interface: iconv()
    • Attribute: Thread safety
    • Value: MT-Safe race:cd

the iconv() function is MT-Safe, as long as callers arrange for mutual exclusion on the cd argument. so like, thread-safe but only if y'all take turns with cd, okay?? no fighting over the descriptor ๐Ÿค


๐ŸŒˆ STANDARDS ๐ŸŒˆ

POSIX.1-2008.


๐Ÿ•ฐ๏ธ HISTORY ๐Ÿ•ฐ๏ธ

glibc 2.1. POSIX.1-2001.


๐Ÿ“ NOTES ๐Ÿ“

  • in each series of calls to iconv(), the last one should be a call with inbuf or *inbuf equal to NULL, so you can flush out any partially converted input. don't skip the flush, bestie, it's not optional in spirit ๐Ÿšฟ
  • even though inbuf and outbuf are typed as char **, that does not mean the objects they point to can be interpreted as C strings or as arrays of characters. the interpretation of character byte sequences is handled internally by the conversion functions. in some encodings, a zero byte may be a valid part of a multibyte character. so do NOT go treating them as cute lil strings, that's a trap ๐Ÿ™ˆ
  • the caller of iconv() must ensure that the pointers passed to the function are suitable for accessing characters in the appropriate character set. this includes ensuring correct alignment on platforms that have tight restrictions on alignment. alignment matters, periodt.

๐Ÿซถ SEE ALSO ๐Ÿซถ

iconv_close(3), iconv_open(3), iconvconfig(8)


๐Ÿ’– that's the whole page! go convert something and remember: flush your state, check your errno, and never assume char ** means "string" ๐Ÿ’–

and that's a wrap on iconv(3), straight from Linux man-pages 6.20, dated 2026-02-08. mwah ๐Ÿ’…โœจ

๐Ÿ“ฆ where this page comes from
  • arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • ๐Ÿ“œ the page's license: GPL-2.0-or-later
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms