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
mainfunction, 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:
| Header | Domain |
|---|---|
<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 streams —
stdin,stdout,stderr. Each is aFILE *available without explicit opening. - File operations —
fopen,freopen,fclose,tmpfile,tmpnam. Treated in File I/O. - Character I/O —
fgetc,fputc,getchar,putchar,ungetc. - Line I/O —
fgets,fputs,puts. The historicalgetswas removed in C11; do not use it. - Formatted I/O —
printf,fprintf,sprintf,snprintf,vprintf,vfprintf,vsprintf,vsnprintffor output;scanf,fscanf,sscanf,vscanf,vfscanf,vsscanffor input. - Binary I/O —
fread,fwrite. - Positioning —
fseek,ftell,rewind,fgetpos,fsetpos. - Buffer control —
fflush,setbuf,setvbuf. - Error checking —
feof,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:
- Allocation —
malloc,calloc,realloc,free,aligned_alloc. Treated in Memory. - Process termination —
exit,_Exit,abort,atexit,at_quick_exit,quick_exit.exitruns cleanup handlers andatexit-registered functions;abortdoes not. - Environment —
getenv,setenv(POSIX),system.getenv("HOME")is the conventional way to read environment variables. - String conversions —
atoi,atol,atof(the simple parsers; report no errors);strtol,strtoll,strtoul,strtoull,strtod,strtof,strtold(the better parsers; seterrnoand write the position of the first unconsumed character). - Pseudo-random numbers —
rand,srand. The standardrandis 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 algorithms —
qsort,bsearch. Both take a comparator; treated in Data structures. - Integer arithmetic —
abs,labs,llabs,div,ldiv,lldiv. Thedivfamily returns a structure with both quotient and remainder. - Multibyte conversions —
mblen,mbstowcs,wcstombsfor 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 exponential —
pow,sqrt,cbrt,exp,exp2,exp10,log,log2,log10,expm1,log1p. - Trigonometric —
sin,cos,tan,asin,acos,atan,atan2. - Hyperbolic —
sinh,cosh,tanh,asinh,acosh,atanh. - Rounding and absolute —
floor,ceil,round,trunc,nearbyint,rint,fabs. - Decomposition —
frexp,ldexp,modf. - Floating classification —
isnan,isinf,isfinite,isnormal,signbit. These are macros, not functions; they accept any floating type. - Special —
erf,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 types —
time_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 acquisition —
time(NULL)for the current calendar time,clock()for CPU time,timespec_get(&ts, TIME_UTC)for sub-second wall-clock (C11). - Conversion —
gmtimeandlocaltimeconverttime_ttostruct tm;mktimeis the reverse. - Formatting —
strftimeformats astruct tmaccording to a format string;asctimeandctimeproduce 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:
| Predicate | True 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, plusint_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 sinceboolis 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 ofwchar_tis 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 returningtrueon 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.