Polyglot
Languages C stdlib
C § stdlib

Standard library

The C standard library is small. Compared with the standard libraries of comparable contemporary languages, it omits significantly more than it includes: there are no containers, no regular expressions, no JSON parsing, no HTTP client, no compression, no cryptography. What the standard library does provide is the foundation that most C programs use directly and that nearly every higher-level library is built on: input and output, memory allocation, string handling, mathematics, character classification, time, and a small set of utility functions. The library is structured into seventeen-or-so headers, each declaring a coherent group of facilities. A working C programmer becomes familiar with their contents the way one becomes familiar with an alphabet: not by memorising every detail but by knowing which header to look in for which concern.

This page surveys the principal headers. For headers covered in depth elsewhere — <stdio.h>’s file half in File I/O, the string and memory functions in Strings, the threading primitives in Concurrency — the survey provides only the bird’s-eye view and a cross-reference.

The shape of the library

The C standard distinguishes hosted and freestanding implementations:

  • A hosted implementation provides the full library and runs in the conventional environment with a main function, command-line arguments, an environment, and standard streams.
  • A freestanding implementation provides only a small subset (typically <float.h>, <iso646.h>, <limits.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, <stdint.h>, plus the few atomic and threading bits where they apply) and is the conventional target for embedded and kernel code.

Most discussion of “the C standard library” assumes a hosted implementation. Freestanding C programs typically supply replacements for the parts of the library they need.

The library is small enough that the headers can be enumerated. The standard’s seventeen mandatory headers are:

HeaderDomain
<stdio.h>input and output
<stdlib.h>general utilities — allocation, conversion, exit, pseudo-random
<string.h>byte and string manipulation
<math.h>mathematical functions
<time.h>time and date
<ctype.h>character classification and conversion
<errno.h>error reporting
<assert.h>assertions
<stdarg.h>variable arguments
<setjmp.h>non-local jumps
<signal.h>signal handling
<locale.h>locale-aware operations
<limits.h>, <float.h>type limits
<stdint.h>, <stddef.h>, <stdbool.h>type aliases and definitions
<wchar.h>, <uchar.h>, <wctype.h>wide and Unicode characters

C11 added <stdatomic.h> and <threads.h>, both optional. C23 added <stdbit.h> (bit-manipulation operations) and <stdckdint.h> (checked integer arithmetic), both new.

<stdio.h> — input and output

The principal facilities:

  • The standard streamsstdin, stdout, stderr. Each is a FILE * available without explicit opening.
  • File operationsfopen, freopen, fclose, tmpfile, tmpnam. Treated in File I/O.
  • Character I/Ofgetc, fputc, getchar, putchar, ungetc.
  • Line I/Ofgets, fputs, puts. The historical gets was removed in C11; do not use it.
  • Formatted I/Oprintf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf for output; scanf, fscanf, sscanf, vscanf, vfscanf, vsscanf for input.
  • Binary I/Ofread, fwrite.
  • Positioningfseek, ftell, rewind, fgetpos, fsetpos.
  • Buffer controlfflush, setbuf, setvbuf.
  • Error checkingfeof, ferror, clearerr, perror.

The format-string mini-language used by printf and scanf is treated in Strings. The file half — opening, reading, writing, closing, positioning — is treated in File I/O.

<stdlib.h> — general utilities

The principal facilities:

  • Allocationmalloc, calloc, realloc, free, aligned_alloc. Treated in Memory.
  • Process terminationexit, _Exit, abort, atexit, at_quick_exit, quick_exit. exit runs cleanup handlers and atexit-registered functions; abort does not.
  • Environmentgetenv, setenv (POSIX), system. getenv("HOME") is the conventional way to read environment variables.
  • String conversionsatoi, atol, atof (the simple parsers; report no errors); strtol, strtoll, strtoul, strtoull, strtod, strtof, strtold (the better parsers; set errno and write the position of the first unconsumed character).
  • Pseudo-random numbersrand, srand. The standard rand is famously poor; production code uses better generators (the Mersenne Twister, the PCG family, the SplitMix64) from external libraries. C23 introduced <stdbit.h> and discussion is ongoing to add better random facilities.
  • Generic algorithmsqsort, bsearch. Both take a comparator; treated in Data structures.
  • Integer arithmeticabs, labs, llabs, div, ldiv, lldiv. The div family returns a structure with both quotient and remainder.
  • Multibyte conversionsmblen, mbstowcs, wcstombs for the legacy multibyte interface. Modern code typically uses <uchar.h> instead.

The strtol family is the conventional input-parsing tool. It takes a string, a pointer to a pointer that will receive the position of the first unconsumed character, and a base; it sets errno to ERANGE on overflow:

errno = 0;
char *end;
long  v = strtol(input, &end, 10);
if (end == input || *end != '\0' || errno == ERANGE) {
    /* parse error */
}

<string.h> — byte and string manipulation

Two families of functions:

  • String functions (operate on null-terminated char *) — strlen, strcpy, strncpy, strcat, strncat, strcmp, strncmp, strchr, strrchr, strstr, strspn, strcspn, strpbrk, strtok, strerror.
  • Memory functions (operate on void * with explicit lengths) — memcpy, memmove, memcmp, memset, memchr.

The string functions follow the null-terminator convention; the memory functions do not. For arbitrary byte data, the memory functions are the appropriate primitive; for text, the string functions are. The full treatment of strings is in Strings.

memcpy requires that the source and destination not overlap; memmove is the variant that handles overlap correctly. Compiler optimisers replace short, fixed-size memcpy calls with single-instruction copies; the function call is rarely a real cost.

<math.h> — mathematical functions

The principal facilities:

  • Power and exponentialpow, sqrt, cbrt, exp, exp2, exp10, log, log2, log10, expm1, log1p.
  • Trigonometricsin, cos, tan, asin, acos, atan, atan2.
  • Hyperbolicsinh, cosh, tanh, asinh, acosh, atanh.
  • Rounding and absolutefloor, ceil, round, trunc, nearbyint, rint, fabs.
  • Decompositionfrexp, ldexp, modf.
  • Floating classificationisnan, isinf, isfinite, isnormal, signbit. These are macros, not functions; they accept any floating type.
  • Specialerf, erfc, tgamma, lgamma, j0, j1, jn, y0, y1, yn (the Bessel functions are POSIX, not C).

Each function is available in three precisions: the default double, the float form (suffix f: sqrtf), and the long double form (suffix l: sqrtl). C99’s <tgmath.h> provides type-generic macros that select the appropriate form.

The principal practical pitfall: linking against <math.h> on Unix requires -lm on the link command. The function declarations are in the header but the definitions are in a separate library:

cc program.c -o program -lm

A program that fails to link with “undefined reference to sqrt” is almost always missing -lm.

<time.h> — time and date

The principal facilities:

  • Time typestime_t (calendar time, conventionally seconds since the Unix epoch), struct tm (broken-down time), clock_t (CPU time), struct timespec (sub-second precision, since C11).
  • Time acquisitiontime(NULL) for the current calendar time, clock() for CPU time, timespec_get(&ts, TIME_UTC) for sub-second wall-clock (C11).
  • Conversiongmtime and localtime convert time_t to struct tm; mktime is the reverse.
  • Formattingstrftime formats a struct tm according to a format string; asctime and ctime produce a fixed format (and are deprecated in C23).

A typical idiom for a wall-clock timestamp:

#include <time.h>

time_t now = time(NULL);
char   buf[32];
strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", localtime(&now));

strftime’s format directives (%Y, %m, %H, …) follow a small grammar similar to printf’s, listed in the standard.

For high-resolution timing, timespec_get (C11) or POSIX’s clock_gettime provide nanosecond resolution. clock returns CPU time in implementation-defined units (CLOCKS_PER_SEC is the divisor); it is appropriate for benchmarking but not for wall-clock timing.

<ctype.h> — character classification

A set of macros (or functions) for classifying characters:

PredicateTrue for
isdigit(c)digits 0–9
isalpha(c)letters
isalnum(c)letters and digits
isspace(c)whitespace (space, tab, newline, return, form feed, vertical tab)
isupper(c)uppercase letters
islower(c)lowercase letters
isxdigit(c)hexadecimal digits
ispunct(c)printing punctuation
iscntrl(c)control characters
isprint(c)printable characters (including space)
isgraph(c)printable non-space

Plus two case-conversion functions:

  • toupper(c) — converts a lowercase letter to uppercase; passes others through.
  • tolower(c) — converts an uppercase letter to lowercase.

The argument must be representable as unsigned char or be EOF; passing a signed char with the high bit set produces undefined behaviour. The conventional safe form is to cast to unsigned char before calling:

isdigit((unsigned char)c);

The classification functions are locale-aware: their behaviour can be modified by setlocale to handle non-ASCII characters according to the active locale.

<errno.h> — error reporting

Defines the thread-local errno integer and macros for the standard error values. Treated in Error handling.

<assert.h> — assertions

Defines the assert macro and (since C11) static_assert. Treated in Error handling.

<stdarg.h> — variable arguments

Defines va_list, va_start, va_arg, va_end, and (C99) va_copy, used to access the variadic arguments of a ... function. Treated in Functions.

<setjmp.h> — non-local jumps

Defines jmp_buf, setjmp, and longjmp for non-local control transfer. Treated in Error handling.

<signal.h> — signals

The C standard provides minimal signal handling: signal(SIGINT, handler) registers a handler; raise(SIGINT) triggers a signal. POSIX adds substantially more — sigaction, sigemptyset, sigprocmask, real-time signals — and the POSIX interface is the conventional one in production code.

<locale.h> — locale-aware operations

Defines setlocale for selecting an active locale and localeconv for inspecting its details. The principal effect is on <ctype.h>’s classification functions, on <stdio.h>’s formatting (decimal-point character), and on <string.h>’s strcoll and strxfrm. Most contemporary C programs that handle Unicode use a third-party library (ICU, GLib) rather than relying on <locale.h>.

<limits.h>, <float.h> — type limits

Macros giving the range and precision of the standard arithmetic types:

  • <limits.h>INT_MAX, INT_MIN, UINT_MAX, LONG_MAX, CHAR_BIT, SCHAR_MAX, and so on.
  • <float.h>DBL_MAX, DBL_MIN, DBL_EPSILON, FLT_MAX, LDBL_MAX, and the related precision and exponent macros.

The macros are the portable way to avoid hard-coding type widths.

<stdint.h>, <stddef.h>, <stdbool.h> — type aliases

  • <stdint.h> (C99) — fixed-width integer aliases (int8_t, uint16_t, int32_t, uint64_t, plus int_least*_t, int_fast*_t, intmax_t, uintmax_t, intptr_t, uintptr_t) and the corresponding limits macros (INT32_MAX, etc.).
  • <stddef.h>size_t, ptrdiff_t, wchar_t, NULL, offsetof.
  • <stdbool.h> (C99; deprecated in C23 since bool is now a keyword) — bool, true, false.

The fixed-width types in <stdint.h> are the conventional answer for code that needs specific widths: protocol implementations, file formats, hardware interfaces.

<wchar.h>, <uchar.h>, <wctype.h> — wide and Unicode characters

  • <wchar.h> — wide-character versions of <stdio.h>, <string.h>, <ctype.h> (limited), and <stdlib.h> (multibyte conversions). The width of wchar_t is implementation-defined; portable text handling usually avoids this header.
  • <uchar.h> (C11) — char16_t, char32_t, and conversion functions between multibyte and these portable Unicode representations.
  • <wctype.h> — wide-character versions of the <ctype.h> classification functions.

The conventional contemporary approach to text encoding in C uses UTF-8 in char arrays internally, transcoding to other representations at the boundaries through <uchar.h> or a third-party library.

<stdatomic.h>, <threads.h> — concurrency

Both optional. Treated in Concurrency.

<stdbit.h>, <stdckdint.h> — C23 additions

  • <stdbit.h> — bit-manipulation operations: stdc_count_ones, stdc_count_zeros, stdc_first_leading_one, stdc_first_trailing_one, stdc_bit_width, stdc_bit_floor, stdc_bit_ceil. These are type-generic macros.
  • <stdckdint.h> — checked integer arithmetic: ckd_add, ckd_sub, ckd_mul, each returning true on overflow.

The C23 additions formalise operations that programs have been writing by hand or relying on compiler intrinsics for; uptake is gradual as compilers ship support.

A note on POSIX

POSIX (the IEEE standard for Unix-like systems) extends the C standard library substantially: file-descriptor I/O (open, read, write, close), threads (pthreads), regular expressions (<regex.h>), networking (<sys/socket.h>), processes (fork, exec, wait), terminal control, and much more. POSIX is not part of the C standard, but on Unix-like systems it is universally available, and substantial portions of any production C program targeting such systems will use POSIX rather than ISO C exclusively.

The convention is to mark POSIX-only code paths conditionally (e.g. #if defined(__unix__)) and to keep portable code in the ISO C subset where feasible. Cross-platform projects typically maintain a thin abstraction layer that selects the appropriate API for each platform.