BG C Library
BG C Library
Library Reference
1 Foreword 1
1.1 Audience . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 How to Read This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.3 Platform and Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.4 Official Homepage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.5 Email Policy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.6 Mirroring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.7 Note for Translators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.8 Copyright and Distribution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.9 Dedication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2 The C Language 4
2.1 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1.1 Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1.2 Separators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1.3 Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1.4 Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1.5 Booleans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1.6 Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1.7 Code Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2.1 Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2.2 Pre- and Post-Increment and -Decrement . . . . . . . . . . . . . . . . . . . . . . 5
2.2.3 Comparison Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2.4 Pointer Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2.5 Structure and Union Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2.6 Array Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2.7 Bitwise Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2.8 Assignment Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2.9 The sizeof Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2.10 Type Casts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2.11 _Alignof Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2.12 Comma Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3 Type Specifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.4 Constant Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.5 Composite Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.5.1 struct Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.5.2 union Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.5.3 enum Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.6 Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.7 Compound Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.8 Type Aliases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.9 Additional Type-Related Specifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
i
CONTENTS ii
5.6 isgraph() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.7 islower() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.8 isprint() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.9 ispunct() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
5.10 isspace() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
5.11 isupper() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.12 isxdigit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.13 tolower() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.14 toupper() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
13 <math.h> Mathematics 98
13.1 Math Function Idioms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
13.2 Math Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
CONTENTS iv
Foreword
The door slowly creaks open revealing a long hall with dusty stacks of books of lore…
I admit, maybe not that.
But you have found the Library Reference portion of Beej’s Guide to C!
This isn’t a tutorial, but rather is a comprehensive set of manual pages (or man pages as Unix hackers like to
say) that define every function in the C Standard Library, complete with examples.
“This book, sir, contains every word in our beloved language.”
“Every single one, sir?”
“Every single one, sir!”
“Ah, well in that case, sir, I hope you will not object if I also offer the doctor my most enthusiastic
contrafribularities.”
–Blackadder toying with Dr. Samuel Johnson
There are, in fact, a number of functions left out of this guide, most notably all the optional “safe” functions
(with a _s suffix).
But everything you’re likely to want is definitely covered in here. With examples.
Probably.
1.1 Audience
This guide is for people who are at least modestly proficient in C.
If you are not one of those people and wish to become one of those people, I can wholeheartedly recommend
with zero bias the book Beej’s Guide to C Programming1 , freely available wherever the Internet is sold.
1
Chapter 1. Foreword 2
1.6 Mirroring
You are more than welcome to mirror this site, whether publicly or privately. If you publicly mirror the site
and want me to link to it from the main page, drop me a line at beej@beej.us.
2
https://en.wikipedia.org/wiki/ANSI_C
3
https://en.wikipedia.org/wiki/POSIX
4
https://visualstudio.microsoft.com/vs/community/
5
https://docs.microsoft.com/en-us/windows/wsl/install-win10
6
https://developer.apple.com/xcode/
7
https://beej.us/guide/bgclr/
Chapter 1. Foreword 3
1.9 Dedication
The hardest things about writing these guides are:
• Learning the material in enough detail to be able to explain it
• Figuring out the best way to explain it clearly, a seemingly-endless iterative process
• Putting myself out there as a so-called authority, when really I’m just a regular human trying to make
sense of it all, just like everyone else
• Keeping at it when so many other things draw my attention
A lot of people have helped me through this process, and I want to acknowledge those who have made this
book possible.
• Everyone on the Internet who decided to help share their knowledge in one form or another. The free
sharing of instructive information is what makes the Internet the great place that it is.
• The volunteers at cppreference.com8 who provide the bridge that leads from the spec to the real world.
• The helpful and knowledgeable folks on comp.lang.c9 and r/C_Programming10 who got me through
the tougher parts of the language.
• Everyone who submitted corrections and pull-requests on everything from misleading instructions to
typos.
Thank you! ♥
8
https://en.cppreference.com/
9
https://groups.google.com/g/comp.lang.c
10
https://www.reddit.com/r/C_Programming/
Chapter 2
The C Language
This is just a quick overview of the fashionable and fun highlights of the syntax, keywords, and other animals
in the C menagerie.
2.1 Background
Some things you’ll need to make sense of the examples, below.
2.1.1 Comments
Comments in C start with // and go to the end of a line.
Multiline comments begin with /* and continue until a closing */.
2.1.2 Separators
Expressions in C are separated by semicolons (;). These tend to appear at the ends of lines.
2.1.3 Expressions
If it’s not a keyword or other reserved punctuation, it tends to be an expression. Think “math including
function calls”.
2.1.4 Statements
Think if, while, etc. Executable keywords.
2.1.5 Booleans
Ignoring the bool type, zero is false and non-zero is true.
2.1.6 Blocks
Multiple expressions and flow control keywords can be wrapped up in a block, made up of { followed by
one or more expressions or statements, followed by }.
4
Chapter 2. The C Language 5
2.2 Operators
2.2.1 Arithmetic Operators
The arithmetic operators: +, -, *, /, % (remainder).
Division is integer if all arguments are integers. Otherwise it’s a floating result.
You can also negate an expression by putting - in front of it. (You can also put a + in front of it—this
doesn’t do anything mathematically, but it causes the Usual Arithmetic Conversions to be performed on the
expression.)
The pre-increment (++) and pre-decrement (--) operators (before the variable) do their work before the rest
of the expression has been evaluated.
int x = 10;
int y = 20;
int z = 30;
This is syntactic sugar over pointer arithmetic and referencing. The above line is equivalent to:
*(a + 10) = 99;
There are compound assignment operators for many of the other operators.
Arithmetic: +=, -=, *=, /=, and %=.
Bitwise: |=, &=, ~=, and ^=.
You can also specify a raw type name in there by wrapping it in parentheses:
size_t x = sizeof(int);
float f = (float)x / y;
Any type can be the argument to the operator, which must be in parenthesis. Unlike sizeof, the argument
cannot be an expression.
printf("Alignment of int is %zu\n", alignof(int));
Usually this is used in the various clauses in loops. For example, we can do multiple assignments in a for
loop, and have multiple post expressions like this:
for (i = 2, j = 10; i < 100; i++, j += 4) { ... }
_Bool is a Boolean type. This becomes bool in C23. Earlier versions of C must include <stdbool.h> to
get bool.
_Complex indicates a complex floating type type, when paired with such a type. Include <complex.h> to
use complex instead.
1
This doesn’t change the type of x in other contexts—it’s just in this one usage in this expression.
Chapter 2. The C Language 8
_Imaginary is an optional keyword used to specify an imaginary type (the imaginary part of a complex
number) when paired with a floating type. Include <complex.h> to use imaginary instead. Neither GCC
nor clang support this.
imaginary float f = 2.3*I;
_Generic is a type “switcher” that allows you to emit different code at compile time depending on the type
of the data.
123.4F float
123.4 double
123.4L long double
'a' char
"hello, world" char* (string)
And you can specify floats in hex! Except in this case the exponent is still in decimal, and the base is 2
instead of 10:
0x1.2p3 0x1.2 x 2^3
};
struct animal a;
struct animal b = {"goat", 4};
struct animal c = {.name="goat", .leg_count=4};
Accessing is done with the dot operator (.) or, if the variable is a pointer to a struct, the arrow operator
(->).
struct animal *p = b;
printf("%d\n", b.leg_count);
printf("%d\n", p->leg_count);
union dt a;
union dt b = {6}; // Initializes "distance", the first field
union dt c = {.distance=6}; // Initializes "distance"
union dt d = {.time=6}; // Initializes "time"
Accessing is done with the dot operator (.) or, if the variable is a pointer to a union, the arrow operator (->).
union dt *p = b;
printf("%d\n", b.time);
printf("%d\n", p->time);
if (a == CAT)
printf("The animal is a cat.\n");
Chapter 2. The C Language 10
The names have numeric values starting with zero and counting up. (In the example above, DOG would be
3.)
The numeric value can be overridden by specifying an integer exactly. Subsequent values increment from
the specified one.
enum animal {
ANTELOPE = 4,
BADGER, // Will be 5
CAT, // Will be 6
DOG = 3,
ELEPHANT, // Will be 4
FISH // Will be 5
};
As above, duplicate values are not illegal, but might be of marginal usefulness.
2.6 Initializers
You can do this when the variable is defined, but not elsewhere.
Initializing basic types:
int x = 12;
float y = 1.2;
char c = 'a';
char *s = "Hello, world!";
Initializing structs:
struct s {
int a;
float b;
};
Initializing unions:
Chapter 2. The C Language 11
union u {
int a;
float b;
};
3 struct s {
4 int a, b;
5 };
6
7 int add(struct s x)
8 {
9 return x.a + x.b;
10 }
11
12 int main(void)
13 {
14 int t = add((struct s){.a=2, .b=4}); // <-- Here
15
16 printf("%d\n", t);
17 }
time_counter t = 3490;
auto is the default, so it’s basically never used. Indicates automatic storage duration (things like local vari-
ables get freed automatically when they fall out of scope). In C23 this keyword changes to indicate type
inference like C++.
register indicates that accessing this variable should be as quick as possible. Restricts some usage of the
variable giving the compiler a chance to optimize. Rare in daily use.
static at function scope indicates that this variable’s value should persist from call to call. At file scope
indicates that this variable should not be visible outside of this source file.
extern indicates that this variable refers to one declared in another source file.
_Thread_local means that every thread gets its own copy of this variable. You can use thread_local if
you include <threads.h>.
const int a
const int *p
int * const p
const int * const p
int * restrict p
volatile int a
atomic int a
const means the value can’t be modified. You can use it with pointers, as well:
const int a = 10; // Can't modify "a"
const int *p = &b // Can't modify the thing "p" points to ("b")
int *const p = &b // Can't modify "p"
const int *const p = &b // Can't modify "p" or the thing it points to
restrict on a pointer means that there will only be one pointer to the item in question, freeing the compiler
to make some optimizations.
volatile indicates that the value in a variable might change at any time and should be loaded from memory
instead of being kept in a register. Usually used with memory-mapped hardware.
_Atomic (or atomic if you include <stdatomic.h>) tells the compiler that reads or writes to this type
should happen atomically. (This might be accomplished with a lock depending on the platform and type.)
2.10 if Statement
if (boolean_expression) code;
if (boolean_expression) {
code;
code;
code;
}
Chapter 2. The C Language 14
if (boolean_expression) {
code;
code;
} else
code;
if (boolean_expression) {
code;
code;
} else if {
code;
code;
code;
} else {
code;
}
You can separate parts of the expressions with the comma operator:
for (i = 0, j = 5; i < 10; i++, j *= 3) {
code;
code;
}
while (boolean_expression) {
code;
code;
}
do {
code;
code;
} while (boolean_expression);
case constant:
code;
code;
break;
default:
code;
break;
}
The final break in the switch is unnecessary if there are no cases after it.
If the break isn’t present, the case falls through to the next one. It’s nice to put a comment to that effect so
other devs don’t hate you.
switch (expression) {
case constant:
code;
code;
// fall through!
case constant:
code;
Chapter 2. The C Language 16
break;
}
if (boolean_expression)
break;
code;
}
if (boolean_expression_2)
continue;
code;
code;
}
int i = 0;
loop:
printf("%d\n", i++);
if (i < 10)
Chapter 2. The C Language 17
goto loop;
}
2.20 Functions
You need to specify the return type and parameter types for the function, and the body goes in a block
afterward.
Variables in the function are local to that function.
// Function that adds two numbers
return sum;
}
Functions that return nothing should be return type void. Functions that accept no parameters should have
void as the parameter list.
// All side effects, all the time!
void foo(void)
{
some_global = 12;
printf("Here we go!\n");
}
int main(void)
int main(int argc, char *argv[])
total += n;
}
return total;
}
2
Note that this implication only for main(), and not for any other functions.
Chapter 3
Macro Description
assert() Runtime assertion
static_assert() Compile-time assertion
This functionality has to do with things that Should Never Happen™. If you have something that should
never be true and you want your program to bomb out because it happened, this is the header file for you.
There are two types of assertions: compile-time assertions (called “static assertions”) and runtime assertions.
If the assertion fails (i.e. the thing that you need to be true is not true) then the program will bomb out either
at compile-time or runtime.
3.1 Macros
If you define the macro NDEBUG before you include <assert.h>, then the assert() macro will have no
effect. You can define NDEBUG to be anything, but 1 seems like a good value.
Since assert() causes your program to bomb out at runtime, you might not desire this behavior when you
go into production. Defining NDEBUG causes assert() to be ignored.
NDEBUG has no effect on static_assert().
3.2 assert()
Bomb out at runtime if a condition fails
Synopsis
#include <assert.h>
19
Chapter 3. <assert.h> Runtime and Compile-time Diagnostics 20
Description
You pass in an expression to this macro. If it evaluates to false, the program will crash with an assertion
failure (by calling the abort() function).
Basically, you’re saying, “Hey, I’m assuming this condition is true, and if it’s not, I don’t want to continue
running.”
This is used while debugging to make sure no unexpected conditions arise. And if you find during develop-
ment that the condition does arise, maybe you should modify the code to handle it before going to production.
If you’ve defined the macro NDEBUG to any value before <assert.h> was included, the assert() macro is
ignored. This is a good idea before production.
Unlike static_assert(), this macro doesn’t allow you to print an arbitrary message. If you want to do
this, you can roll your own assert as a preprocessor macro:
#define ASSERT(c, m) \
do { \
if (!(c)) { \
fprintf(stderr, __FILE__ ":%d: assertion %s failed: %s\n", \
__LINE__, #c, m); \
exit(1); \
} \
} while(0)
Return Value
This macro doesn’t return (since it calls abort() which never returns).
If NDEBUG is set, the macro evaluates to ((void)0), which does nothing.
Example
Here’s a function that divides the size of our goat herd. But we’re assuming we’ll never get a 0 passed to us.
So we assert that amount != 0… and if it is, the program aborts/
1 //#define NDEBUG 1 // uncomment this to disable the assert
2
3 #include <stdio.h>
4 #include <assert.h>
5
12 goat_count /= amount;
13 }
14
15 int main(void)
16 {
17 divide_goat_herd_by(2); // OK
18
When I run this and pass 0 to the function, I get the following on my system (the exact output may vary):
assert: assert.c:10: divide_goat_herd_by: Assertion `amount != 0' failed.
See Also
static_assert(), abort()
3.3 static_assert()
Bomb out at compile-time if a condition fails
Synopsis
#include <assert.h>
static_assert(constant-expression, string-literal);
Description
This macro prevents your program from even compiling if a condition isn’t true.
And it prints the string literal you give it.
Basically if constant-expression is false, then compilation will cease and the string-literal will be
printed.
The constant expression must be truly constant–just values, no variables. And the same is true for the string
literal: no variables, just a literal string in double quotes. (It has to be this way since the program’s not
running at this point.)
Return Value
Not applicable, as this is a compile-time feature.
Example
Here’s a partial example with an algorithm that presumably has poor performance or memory issues if the
size of the local array is too large. We prevent that eventuality at compile-time by catching it with the
static_assert().
1 #include <stdio.h>
2 #include <assert.h>
3
4 #define ARRAY_SIZE 16
5
6 int main(void)
7 {
8 static_assert(ARRAY_SIZE > 32, "ARRAY_SIZE too small");
9
10 int a[ARRAY_SIZE];
11
12 a[32] = 10;
Chapter 3. <assert.h> Runtime and Compile-time Diagnostics 22
13
14 printf("%d\n", a[32]);
15 }
On my system, when I try to compile it, this prints (your output may vary):
In file included from static_assert.c:2:
static_assert.c: In function ‘main’:
static_assert.c:8:5: error: static assertion failed: "ARRAY_SIZE too small"
8 | static_assert(ARRAY_SIZE > 32, "ARRAY_SIZE too small");
| ^~~~~~~~~~~~~
See Also
assert()
Chapter 4
The complex functions in this reference section come in three flavors each: double complex, float com-
plex, and long double complex.
The float variants end with f and the long double variants end with l, e.g. for complex cosine:
ccos() double complex
ccosf() float complex
ccosl() long double complex
The table below only lists the double complex version for brevity.
Function Description
cabs() Compute the complex absolute value
cacos() Compute the complex arc-cosine
cacosh() Compute the complex arc hyperbolic cosine
carg() Compute the complex argument
casin() Compute the complex arc-sine
casinh() Compute the complex arc hyperbolic sine
catan() Compute the complex arc-tangent
catanh() Compute the complex arc hyperbolic tangent
ccos() Compute the complex cosine
ccosh() Compute the complex hyperbolic cosine
cexp() Compute the complex base-𝑒 exponential
cimag() Returns the imaginary part of a complex number
clog() Compute the complex logarithm
CMPLX() Build a complex value from real and imaginary types
conj() Compute the conjugate of a complex number
cproj() Compute the projection of a complex number
creal() Returns the real part of a complex number
csin() Compute the complex sine
csinh() Compute the complex hyperbolic sine
csqrt() Compute the complex square root
ctan() Compute the complex tangent
ctanh() Compute the complex hyperbolic tangent
23
Chapter 4. <complex.h> Complex Number Functionality 24
You can test for complex number support by looking at the __STDC_NO_COMPLEX__ macro. If it’s defined,
complex numbers aren’t available.
There are possibly two types of numbers defined: complex and imaginary. No system I’m currently aware
of implements imaginary types.
The complex types, which are a real value plus a multiple of 𝑖, are:
float complex
double complex
long double complex
The latter has the advantage of handing special cases of complex numbers correctly (like those involving
infinity or signed zeroes) as if _Imaginary_I were present, even if it’s not.
All angular values are in radians.
Some functions have discontinuities called branch cuts. Now, I’m no mathematician so I can’t really talk
sensibly about this, but if you’re here, I like to think you know what you’re doing when it comes to this side
of things.
If you system has signed zeroes, you can tell which side of the cut you’re on by the sign. And you can’t if
you don’t. The spec elaborates:
Implementations that do not support a signed zero […] cannot distinguish the sides of branch cuts.
These implementations shall map a cut so the function is continuous as the cut is approached
coming around the finite endpoint of the cut in a counter clockwise direction. (Branch cuts for
the functions specified here have just one finite endpoint.) For example, for the square root
function, coming counter clockwise around the finite endpoint of the cut along the negative real
axis approaches the cut from above, so the cut maps to the positive imaginary axis.
Finally, there’s a pragma called CX_LIMITED_RANGE that can be turned on and off (default is off). You can
turn it on with:
#pragma STDC CX_LIMITED_RANGE ON
It allows for certain intermediate operations to underflow, overflow, or deal badly with infinity, presumably
for a tradeoff in speed. If you’re sure these types of errors won’t occur with the numbers you’re using AND
you’re trying to get as much speed out as you can, you could turn this macro on.
The spec also elaborates here:
Chapter 4. <complex.h> Complex Number Functionality 25
The purpose of the pragma is to allow the implementation to use the formulas:
(𝑥 + 𝑖𝑦) × (𝑢 + 𝑖𝑣) = (𝑥𝑢 − 𝑦𝑣) + 𝑖(𝑦𝑢 + 𝑥𝑣)
(𝑥 + 𝑖𝑦)/(𝑢 + 𝑖𝑣) = [(𝑥𝑢 + 𝑦𝑣) + 𝑖(𝑦𝑢 − 𝑥𝑣)]/(𝑢2 + 𝑣2 )
|𝑥 + 𝑖𝑦| = √𝑥2 + 𝑦2
where the programmer can determine they are safe.
Synopsis
#include <complex.h>
Description
Computes the complex arc-cosine of a complex number.
The complex number z will have an imaginary component in the range [0, 𝜋], and the real component is
unbounded.
There are branch cuts outside the interval [−1, +1] on the real axis.
Return Value
Returns the complex arc-cosine of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 8 + 1.5708 * I;
7
Output:
Chapter 4. <complex.h> Complex Number Functionality 26
See Also
ccos(), casin(), catan()
Synopsis
#include <complex.h>
Description
Computes the complex arc-sine of a complex number.
The complex number z will have an imaginary component in the range [−𝜋/2, +𝜋/2], and the real compo-
nent is unbounded.
There are branch cuts outside the interval [−1, +1] on the real axis.
Return Value
Returns the complex arc-sine of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 8 + 1.5708 * I;
7
Output:
Result: 1.375476 + 2.788006i
Chapter 4. <complex.h> Complex Number Functionality 27
See Also
csin(), cacos(), catan()
Synopsis
#include <complex.h>
Description
Computes the complex arc-tangent of a complex number.
The complex number z will have an real component in the range [−𝜋/2, +𝜋/2], and the imaginary compo-
nent is unbounded.
There are branch cuts outside the interval [−𝑖, +𝑖] on the imaginary axis.
Return Value
Returns the complex arc-tangent of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double wheat = 8;
7 double sheep = 1.5708;
8
Output:
Result: 1.450947 + 0.023299i
Chapter 4. <complex.h> Complex Number Functionality 28
See Also
ctan(), cacos(), casin()
Synopsis
#include <complex.h>
Description
Computes the complex cosine of a complex number.
Return Value
Returns the complex cosine of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 8 + 1.5708 * I;
7
Output:
Result: -0.365087 + -2.276818i
See Also
csin(), ctan(), cacos()
Chapter 4. <complex.h> Complex Number Functionality 29
Synopsis
#include <complex.h>
Description
Computes the complex sine of a complex number.
Return Value
Returns the complex sine of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 8 + 1.5708 * I;
7
Output:
Result: 2.482485 + -0.334840i
See Also
ccos(), ctan(), casin()
Synopsis
Chapter 4. <complex.h> Complex Number Functionality 30
#include <complex.h>
Description
Computes the complex tangent of a complex number.
Return Value
Returns the complex tangent of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 8 + 1.5708 * I;
7
Output:
Result: -0.027073 + 1.085990i
See Also
ccos(), csin(), catan()
Synopsis
#include <complex.h>
Description
Computes the complex arc hyperbolic cosine of a complex number.
There is a branch cut at values less than 1 on the real axis.
The return value will be non-negative on the real number axis, and in the range [−𝑖𝜋, +𝑖𝜋] on the imaginary
axis.
Return Value
Returns the complex arc hyperbolic cosine of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 8 + 1.5708 * I;
7
Output:
Result: 2.788006 + 0.195321i
See Also
casinh(), catanh(), acosh()
Synopsis
#include <complex.h>
Description
Computes the complex arc hyperbolic sine of a complex number.
Chapter 4. <complex.h> Complex Number Functionality 32
There are branch cuts outside [−𝑖, +𝑖] on the imaginary axis.
The return value will be unbounded on the real number axis, and in the range [−𝑖𝜋/2, +𝑖𝜋/2] on the imag-
inary axis.
Return Value
Returns the complex arc hyperbolic sine of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 8 + 1.5708 * I;
7
Output:
Result: 2.794970 + 0.192476i
See Also
cacosh(), catanh(), asinh()
Synopsis
#include <complex.h>
Description
Computes the complex arc hyperbolic tangent of a complex number.
There are branch cuts outside [−1, +1] on the real axis.
The return value will be unbounded on the real number axis, and in the range [−𝑖𝜋/2, +𝑖𝜋/2] on the imag-
inary axis.
Chapter 4. <complex.h> Complex Number Functionality 33
Return Value
Returns the complex arc hyperbolic tangent of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 8 + 1.5708 * I;
7
Output:
Result: 0.120877 + 1.546821i
See Also
cacosh(), casinh(), atanh()
Synopsis
#include <complex.h>
Description
Computes the complex hyperbolic cosine of a complex number.
Return Value
Returns the complex hyperbolic cosine of z.
Example
Chapter 4. <complex.h> Complex Number Functionality 34
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 8 + 1.5708 * I;
7
Output:
Result: -0.005475 + 1490.478826i
See Also
csinh(), ctanh(), ccos()
Synopsis
#include <complex.h>
Description
Computes the complex hyperbolic sine of a complex number.
Return Value
Returns the complex hyperbolic sine of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 8 + 1.5708 * I;
7
Chapter 4. <complex.h> Complex Number Functionality 35
Output:
Result: -0.005475 + 1490.479161i
See Also
ccosh(), ctanh(), csin()
Synopsis
#include <complex.h>
Description
Computes the complex hyperbolic tangent of a complex number.
Return Value
Returns the complex hyperbolic tangent of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 8 + 1.5708 * I;
7
Output:
Chapter 4. <complex.h> Complex Number Functionality 36
See Also
ccosh(), csinh(), ctan()
Synopsis
#include <complex.h>
Description
Computes the complex base-𝑒 exponential of z.
Return Value
Returns the complex base-𝑒 exponential of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 1 + 2 * I;
7
Output:
Result: -1.131204 + 2.471727i
See Also
cpow(), clog(), exp()
Chapter 4. <complex.h> Complex Number Functionality 37
Synopsis
#include <complex.h>
Description
Compute the base-𝑒 complex logarithm of z. There is a branch cut on the negative real axis.
The returns value is unbounded on the real axis and in the range [−𝑖𝜋, +𝑖𝜋] on the imaginary axis.
Return Value
Returns the base-𝑒 complex logarithm of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 1 + 2 * I;
7
Output:
Result: 0.804719 + 1.107149i
See Also
cexp(), log()
Synopsis
#include <complex.h>
Description
Computes the complex absolute value of z.
Return Value
Returns the complex absolute value of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 1 + 2 * I;
7
Output:
Result: 2.236068 + 0.000000i
See Also
fabs(), abs()
Synopsis
#include <complex.h>
Description
Computes the complex 𝑥𝑦 .
There is a branch cut for x along the negative real axis.
Return Value
Returns the complex 𝑥𝑦 .
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 1 + 2 * I;
7 double complex y = 3 + 4 * I;
8
Result:
Result: 0.129010 + 0.000000i
See Also
csqrt(), cexp()
Synopsis
#include <complex.h>
Description
Computes the complex square root of z.
There is a branch cut along the negative real axis.
The return value is in the right half of the complex plane and includes the imaginary axis.
Return Value
Returns the complex square root of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 1 + 2 * I;
7
Output:
Result: 1.272020 + 0.786151i
See Also
cpow(), sqrt()
Synopsis
#include <complex.h>
Description
Computes the complex argument (AKA phase angle) of z.
There is a branch cut along the negative real axis.
Chapter 4. <complex.h> Complex Number Functionality 41
Return Value
Returns the complex argument of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 1 + 2 * I;
7
8 double y = carg(x);
9
Output:
Result: 1.107149
Synopsis
#include <complex.h>
Description
Returns the imaginary part of z.
As a footnote, the spec points out that any complex number x is part of the following equivalency:
x == creal(x) + cimag(x) * I;
Return Value
Returns the imaginary part of z.
Chapter 4. <complex.h> Complex Number Functionality 42
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 1 + 2 * I;
7
8 double y = cimag(x);
9
See Also
creal()
Synopsis
#include <complex.h>
Description
These macros build a complex value from real and imaginary types.
Now I know what you’re thinking. “But I can already build a complex value from real and imaginary types
using the I macro, like in the example you’re about to give us.”
double complex x = 1 + 2 * I;
Return Value
Returns the complex number for the given real x and imaginary y components.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = CMPLX(1, 2); // Like 1 + 2 * I
7
Output:
Result: 1.000000 + 2.000000i
See Also
creal(), cimag()
Synopsis
#include <complex.h>
Description
This function computes the complex conjugate1 of z. Apparently it does this by reversing the sign of the
imaginary part, but dammit, I’m a programmer not a mathematician, Jim!
Return Value
Returns the complex conjugate of z
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 1 + 2 * I;
7
Output:
Result: 1.000000 + -2.000000i
Synopsis
#include <complex.h>
Description
Computes the projection of z onto a Riemann sphere2 .
Now we’re really outside my expertise. The spec has this to say, which I’m quoting verbatim because I’m
not knowledgable enough to rewrite it sensibly. Hopefully it makes sense to anyone who would need to use
this function.
1
https://en.wikipedia.org/wiki/Complex_conjugate
2
https://en.wikipedia.org/wiki/Riemann_sphere
Chapter 4. <complex.h> Complex Number Functionality 45
z projects to z except that all complex infinities (even those with one infinite part and one NaN
part) project to positive infinity on the real axis. If z has an infinite part, then cproj(z) is
equivalent to
INFINITY + I * copysign(0.0, cimag(z))
Return Value
Returns the projection of z onto a Riemann sphere.
Example
Fingers crossed this is a remotely sane example…
1 #include <stdio.h>
2 #include <complex.h>
3 #include <math.h>
4
5 int main(void)
6 {
7 double complex x = 1 + 2 * I;
8
13 x = INFINITY + 2 * I;
14 y = cproj(x);
15
Output:
Result: 1.000000 + 2.000000i
Result: inf + 0.000000i
Synopsis
#include <complex.h>
Description
Returns the real part of z.
As a footnote, the spec points out that any complex number x is part of the following equivalency:
x == creal(x) + cimag(x) * I;
Return Value
Returns the real part of z.
Example
1 #include <stdio.h>
2 #include <complex.h>
3
4 int main(void)
5 {
6 double complex x = 1 + 2 * I;
7
8 double y = creal(x);
9
See Also
cimag()
Chapter 5
Function Description
isalnum() Tests if a character is alphabetic or is a digit
isalpha() Returns true if a character is alphabetic
isblank() Tests if a character is word-separating whitespace
iscntrl() Test if a character is a control character
isdigit() Tests if a character is a digit
isgraph() Tests if the character is printable and not a space
islower() Tests if a character is lowercase
isprint() Tests if a character is printable
ispunct() Test if a character is punctuation
isspace() Test if a character is whitespace
isupper() Tests if a character is uppercase
isxdigit() Tests if a character is a hexadecimal digit
tolower() Convert a letter to lowercase
toupper() Convert a letter to uppercase
This collection of macros is good for testing characters to see if they’re of a certain class, such as alphabetic,
numeric, control characters, etc.
Surprisingly, they take int arguments instead of some kind of char. This is so you can feed EOF in for con-
venience if you have an integer representation of that. If not EOF, the value passed in has to be representable
in an unsigned char. Otherwise it’s (dun dun DUUNNNN) undefined behavior. So you can forget about
passing in your UTF-8 multibyte characters.
You can portably avoid this undefined behavior by casting the arguments to these functions to (unsigned
char). This is irksome and ugly, admittedly. The values in the basic character set are all safe to use since
they’re positive values that fit into an unsigned char.
Also, the behavior of these functions varies based on locale.
In many of the pages in this section, I give some examples. These are from the “C” locale, and might vary if
you’ve set a different locale.
Note that wide characters have their own set of classification functions, so don’t try to use these on wchar_ts.
Or else!
47
Chapter 5. <ctype.h> Character Classification and Conversion 48
5.1 isalnum()
Tests if a character is alphabetic or is a digit
Synopsis
#include <ctype.h>
Description
Tests if a character is alphabetic (A-Z or a-z) or a digit (0-9).
Is equivalent to:
isalpha(c) || isdigit(c)
Return Value
Returns true if a character is alphabetic (A-Z or a-z) or a digit (0-9).
Example
1 #include <stdio.h>
2 #include <ctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 printf("%s\n", isalnum('a')? "yes": "no"); // yes
9 printf("%s\n", isalnum('B')? "yes": "no"); // yes
10 printf("%s\n", isalnum('5')? "yes": "no"); // yes
11 printf("%s\n", isalnum('?')? "yes": "no"); // no
12 }
See Also
isalpha(), isdigit()
5.2 isalpha()
Returns true if a character is alphabetic
Synopsis
#include <ctype.h>
Description
Returns true for alphabetic characters (A-Z or a-z).
Technically (and in the “C” locale) equivalent to:
isupper(c) || islower(c)
Extra super technically, because I know you’re dying for this to be extra unnecessarily complex, it can also
include some locale-specific characters for which this is true:
!iscntrl(c) && !isdigit(c) && !ispunct(c) && !isspace(c)
Return Value
Returns true for alphabetic characters (A-Z or a-z).
Or for any of the other crazy stuff in the description, above.
Example
1 #include <stdio.h>
2 #include <ctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 printf("%s\n", isalpha('a')? "yes": "no"); // yes
9 printf("%s\n", isalpha('B')? "yes": "no"); // yes
10 printf("%s\n", isalpha('5')? "yes": "no"); // no
11 printf("%s\n", isalpha('?')? "yes": "no"); // no
12 }
See Also
isalnum()
5.3 isblank()
Tests if a character is word-separating whitespace
Synopsis
#include <ctype.h>
Description
True if the character is a whitespace character used to separate words in a single line.
For example, space (' ') or horizontal tab ('\t'). Other locales might define other blank characters.
Return Value
Returns true if the character is a whitespace character used to separate words in a single line.
Example
1 #include <stdio.h>
2 #include <ctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 printf("%s\n", isblank(' ')? "yes": "no"); // yes
9 printf("%s\n", isblank('\t')? "yes": "no"); // yes
10 printf("%s\n", isblank('\n')? "yes": "no"); // no
11 printf("%s\n", isblank('a')? "yes": "no"); // no
12 printf("%s\n", isblank('?')? "yes": "no"); // no
13 }
See Also
isspace()
5.4 iscntrl()
Test if a character is a control character
Synopsis
#include <ctype.h>
Description
A control character is a locale-specific non-printing character.
For the “C” locale, this means control characters are in the range 0x00 to 0x1F (the character right before
SPACE) and 0x7F (the DEL character).
Basically if it’s not an ASCII (or Unicode less than 128) printable character, it’s a control character in the
“C” locale.
Return Value
Returns true if c is a control character.
Chapter 5. <ctype.h> Character Classification and Conversion 51
Example
1 #include <stdio.h>
2 #include <ctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 printf("%s\n", iscntrl('\t')? "yes": "no"); // yes (tab)
9 printf("%s\n", iscntrl('\n')? "yes": "no"); // yes (newline)
10 printf("%s\n", iscntrl('\r')? "yes": "no"); // yes (return)
11 printf("%s\n", iscntrl('\a')? "yes": "no"); // yes (bell)
12 printf("%s\n", iscntrl(' ')? "yes": "no"); // no
13 printf("%s\n", iscntrl('a')? "yes": "no"); // no
14 printf("%s\n", iscntrl('?')? "yes": "no"); // no
15 }
See Also
isgraph(), isprint()
5.5 isdigit()
Tests if a character is a digit
Synopsis
#include <ctype.h>
Description
Tests if c is a digit in the range 0-9.
Return Value
Returns true if the character is a digit, unsurprisingly.
Example
1 #include <stdio.h>
2 #include <ctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 printf("%s\n", isdigit('0')? "yes": "no"); // yes
Chapter 5. <ctype.h> Character Classification and Conversion 52
See Also
isalnum(), isxdigit()
5.6 isgraph()
Tests if the character is printable and not a space
Synopsis
#include <ctype.h>
Description
Tests if c is any printable character that isn’t a space (' ').
Return Value
Returns true if c is any printable character that isn’t a space (' ').
Example
1 #include <stdio.h>
2 #include <ctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 printf("%s\n", isgraph('0')? "yes": "no"); // yes
9 printf("%s\n", isgraph('a')? "yes": "no"); // yes
10 printf("%s\n", isgraph('B')? "yes": "no"); // yes
11 printf("%s\n", isgraph('?')? "yes": "no"); // yes
12 printf("%s\n", isgraph(' ')? "yes": "no"); // no
13 printf("%s\n", isgraph('\n')? "yes": "no"); // no
14 }
See Also
iscntrl(), isprint()
Chapter 5. <ctype.h> Character Classification and Conversion 53
5.7 islower()
Tests if a character is lowercase
Synopsis
#include <ctype.h>
Description
Tests if a character is lowercase, in the range a-z.
In other locales, there could be other lowercase characters. In all cases, to be lowercase, the following must
be true:
!iscntrl(c) && !isdigit(c) && !ispunct(c) && !isspace(c)
Return Value
Returns true if the character is lowercase.
Example
1 #include <stdio.h>
2 #include <ctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 printf("%s\n", islower('c')? "yes": "no"); // yes
9 printf("%s\n", islower('0')? "yes": "no"); // no
10 printf("%s\n", islower('B')? "yes": "no"); // no
11 printf("%s\n", islower('?')? "yes": "no"); // no
12 printf("%s\n", islower(' ')? "yes": "no"); // no
13 }
See Also
isupper(), isalpha(), toupper(), tolower()
5.8 isprint()
Tests if a character is printable
Synopsis
Chapter 5. <ctype.h> Character Classification and Conversion 54
#include <ctype.h>
Description
Tests if a character is printable, including space (' '). So like isgraph(), except space isn’t left out in the
cold.
Return Value
Returns true if the character is printable, including space (' ').
Example
1 #include <stdio.h>
2 #include <ctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 printf("%s\n", isprint('c')? "yes": "no"); // yes
9 printf("%s\n", isprint('0')? "yes": "no"); // yes
10 printf("%s\n", isprint(' ')? "yes": "no"); // yes
11 printf("%s\n", isprint('\r')? "yes": "no"); // no
12 }
See Also
isgraph(), iscntrl()
5.9 ispunct()
Test if a character is punctuation
Synopsis
#include <ctype.h>
Description
Tests if a character is punctuation.
In the “C” locale, this means:
!isspace(c) && !isalnum(c)
In other locales, there could be other punctuation characters (but they also can’t be space or alphanumeric).
Chapter 5. <ctype.h> Character Classification and Conversion 55
Return Value
True if the character is punctuation.
Example
1 #include <stdio.h>
2 #include <ctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 printf("%s\n", ispunct(',')? "yes": "no"); // yes
9 printf("%s\n", ispunct('!')? "yes": "no"); // yes
10 printf("%s\n", ispunct('c')? "yes": "no"); // no
11 printf("%s\n", ispunct('0')? "yes": "no"); // no
12 printf("%s\n", ispunct(' ')? "yes": "no"); // no
13 printf("%s\n", ispunct('\n')? "yes": "no"); // no
14 }
See Also
isspace(), isalnum()
5.10 isspace()
Test if a character is whitespace
Synopsis
#include <ctype.h>
Description
Tests if c is a whitespace character. These are:
• Space (' ')
• Formfeed ('\f')
• Newline ('\n')
• Carriage Return ('\r')
• Horizontal Tab ('\t')
• Vertical Tab ('\v')
Other locales might specify other whitespace characters. isalnum() is false for all whitespace characters.
Return Value
True if the character is whitespace.
Chapter 5. <ctype.h> Character Classification and Conversion 56
Example
1 #include <stdio.h>
2 #include <ctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 printf("%s\n", isspace(' ')? "yes": "no"); // yes
9 printf("%s\n", isspace('\n')? "yes": "no"); // yes
10 printf("%s\n", isspace('\t')? "yes": "no"); // yes
11 printf("%s\n", isspace(',')? "yes": "no"); // no
12 printf("%s\n", isspace('!')? "yes": "no"); // no
13 printf("%s\n", isspace('c')? "yes": "no"); // no
14 }
See Also
isblank()
5.11 isupper()
Tests if a character is uppercase
Synopsis
#include <ctype.h>
Description
Tests if a character is uppercase, in the range A-Z.
In other locales, there could be other uppercase characters. In all cases, to be uppercase, the following must
be true:
!iscntrl(c) && !isdigit(c) && !ispunct(c) && !isspace(c)
Return Value
Returns true if the character is uppercase.
Example
1 #include <stdio.h>
2 #include <ctype.h>
3
4 int main(void)
5 {
Chapter 5. <ctype.h> Character Classification and Conversion 57
See Also
islower(), isalpha(), toupper(), tolower()
5.12 isxdigit()
Tests if a character is a hexadecimal digit
Synopsis
#include <ctype.h>
Description
Returns true if the character is a hexadecimal digit. Namely if it’s 0-9, a-f, or A-F.
Return Value
True if the character is a hexadecimal digit.
Example
1 #include <stdio.h>
2 #include <ctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 printf("%s\n", isxdigit('B')? "yes": "no"); // yes
9 printf("%s\n", isxdigit('c')? "yes": "no"); // yes
10 printf("%s\n", isxdigit('2')? "yes": "no"); // yes
11 printf("%s\n", isxdigit('G')? "yes": "no"); // no
12 printf("%s\n", isxdigit('?')? "yes": "no"); // no
13 }
See Also
isdigit()
Chapter 5. <ctype.h> Character Classification and Conversion 58
5.13 tolower()
Convert a letter to lowercase
Synopsis
#include <ctype.h>
Description
If the character is uppercase (i.e. isupper(c) is true), this function returns the corresponding lowercase
letter.
Different locales might have different upper- and lowercase letters.
Return Value
Returns the lowercase value for an uppercase letter. If the letter isn’t uppercase, returns it unchanged.
Example
1 #include <stdio.h>
2 #include <ctype.h>
3
4 int main(void)
5 {
6 // changing this char
7 // v
8 printf("%c\n", tolower('B')); // b (made lowercase!)
9 printf("%c\n", tolower('e')); // e (unchanged)
10 printf("%c\n", tolower('!')); // ! (unchanged)
11 }
See Also
toupper(), islower(), isupper()
5.14 toupper()
Convert a letter to uppercase
Synopsis
#include <ctype.h>
Description
If the character is lower (i.e. islower(c) is true), this function returns the corresponding uppercase letter.
Different locales might have different upper- and lowercase letters.
Return Value
Returns the uppercase value for a lowercase letter. If the letter isn’t lowercase, returns it unchanged.
Example
1 #include <stdio.h>
2 #include <ctype.h>
3
4 int main(void)
5 {
6 // changing this char
7 // v
8 printf("%c\n", toupper('B')); // B (unchanged)
9 printf("%c\n", toupper('e')); // E (made uppercase!)
10 printf("%c\n", toupper('!')); // ! (unchanged)
11 }
See Also
tolower(), islower(), isupper()
Chapter 6
Variable Description
errno Holds the error status of the last call
This header defines a single variable1 , errno, that can be checked to see if an error has occurred.
errno is set to 0 on startup, but no library function sets it to 0. If you’re going to use solely it to check
for errors, set it to 0 before the call and then check it after. Not only that, but if there’s no error, all library
functions will leave the value of errno unchanged.
Often, though, you’ll get some error indication from the function you’re calling then check errno to see
what went wrong.
This is commonly used in conjunction with perror() to get a human-readable error message that corre-
sponds to the specific error.
Important Safety Tip: You should never make your own variable called errno—that’s undefined behavior.
Note that the C Spec defines less than a handful of values errno can take on. Unix defines a bunch more2 ,
as does Windows3 .
6.1 errno
Holds the error status of the last call
Synopsis
errno // Type is undefined, but it's assignable
Description
Indicates the error status of the last call (note that not all calls will set this value).
1
Really it’s just required to be a modifiable lvalue, so not necessarily a variable. But you can treat it as such.
2
https://man.archlinux.org/man/errno.3.en
3
https://docs.microsoft.com/en-us/cpp/c-runtime-library/errno-constants?view=msvc-160
60
Chapter 6. <errno.h> Error Information 61
Value Description
0 No error
EDOM Domain error (from math)
EILSEQ Encoding error (from character conversion)
ERANGE Range error (from math)
If you’re doing a number of math functions, you might come across EDOM or ERANGE.
With multibyte/wide character conversion functions, you might see EILSEQ.
And your system might define any other number of values that errno could be set to, all of which will begin
with the letter E.
Fun Fact: you can use EDOM, EILSEQ, and ERANGE with preprocessor directives such as #ifdef. But, frankly,
I’m not sure why you’d do that other than to test their existence.
Example
The following prints an error message, since passing 2.0 to acos() is outside the function’s domain.
1 #include <stdio.h>
2 #include <math.h>
3 #include <errno.h>
4
5 int main(void)
6 {
7 double x;
8
13 if (errno == EDOM)
14 perror("acos");
15 else
16 printf("Answer is %f\n", x);
17
18 return 0;
19 }
Output:
acos: Numerical argument out of domain
The following prints an error message (on my system), since passing 1e+30 to exp() produces a result that’s
outside the range of a double.
1 #include <stdio.h>
2 #include <math.h>
3 #include <errno.h>
4
5 int main(void)
6 {
7 double x;
8
10
13 if (errno == ERANGE)
14 perror("exp");
15 else
16 printf("Answer is %f\n", x);
17
18 return 0;
19 }
Output:
exp: Numerical result out of range
This example tries to convert an invalid character into a wide character, failing. This sets errno to EILSEQ.
We then use perror() to print an error message.
1 #include <stdio.h>
2 #include <string.h>
3 #include <wchar.h>
4 #include <errno.h>
5 #include <locale.h>
6
7 int main(void)
8 {
9 setlocale(LC_ALL, "");
10
20 if (result == (size_t)(-1))
21 perror("mbrtowc"); // mbrtowc: Illegal byte sequence
22 else
23 printf("Converted to L'%lc'\n", wc);
24
25 return 0;
26 }
Output:
mbrtowc: Invalid or incomplete multibyte or wide character
See Also
perror(), mbrtoc16(), c16rtomb(), mbrtoc32(), c32rtomb(), fgetwc(), fputwc(), mbrtowc(),
wcrtomb(), mbsrtowcs(), wcsrtombs(), <math.h>,
Chapter 7
Function Description
feclearexcept() Clear floating point exceptions
fegetexceptflag() Save the floating point exception flags
fesetexceptflag() Restore the floating point exception flags
feraiseexcept() Raise a floating point exception through software
fetestexcept() Test to see if an exception has occurred
fegetround() Get the rounding direction
fesetround() Set the rounding direction
fegetenv() Save the entire floating point environment
fesetenv() Restore the entire floating point environment
feholdexcept() Save floating point state and install non-stop mode
feupdateenv() Restore floating point environment and apply recent exceptions
Type Description
fenv_t The entire floating point environment
fexcept_t A set of floating point exceptions
The “environment” can be thought of as the status at this moment of the floating point processing system:
this includes the exceptions, rounding, etc. It’s an opaque type, so you won’t be able to access it directly, and
it must be done through the proper functions.
If the functions in question exist on your system (they might not be!), then you’ll also have these macros
defined to represent different exceptions:
Macro Description
FE_DIVBYZERO Division by zero
FE_INEXACT Result was not exact, was rounded
63
Chapter 7. <fenv.h> Floating Point Exceptions and Environment 64
Macro Description
FE_INVALID Domain error
FE_OVERFLOW Numeric overflow
FE_UNDERFLOW Numeric underflow
FE_ALL_EXCEPT All of the above combined
The idea is that you can bitwise-OR these together to represent multiple exceptions, e.g. FE_INVALID|FE_OVERFLOW.
The functions, below, that have an excepts parameter will take these values.
See <math.h> for which functions raise which exceptions and when.
7.2 Pragmas
Normally C is free to optimize all kinds of stuff that might cause the flags to not look like you might expect.
So if you’re going to use this stuff, be sure to set this pragma:
#pragma STDC FENV_ACCESS ON
If you do this at global scope, it remains in effect until you turn it off:
#pragma STDC FENV_ACCESS OFF
If you do it in block scope, it has to come before any statements or declarations. In this case, it has effect
until the block ends (or until it is explicitly turned off.)
A caveat: this program isn’t supported on either of the compilers I have (gcc and clang) as of this writing,
so though I have built the code, below, it’s not particularly well-tested.
7.3 feclearexcept()
Clear floating point exceptions
Synopsis
#include <fenv.h>
Description
If a floating point exception has occurred, this function can clear it.
Set excepts to a bitwise-OR list of exceptions to clear.
Passing 0 has no effect.
Return Value
Returns 0 on success and non-zero on failure.
Chapter 7. <fenv.h> Floating Point Exceptions and Environment 65
Example
1 #include <stdio.h>
2 #include <math.h>
3 #include <fenv.h>
4
5 int main(void)
6 {
7 #pragma STDC FENV_ACCESS ON
8
9 double f = sqrt(-1);
10
11 int r = feclearexcept(FE_INVALID);
12
See Also
feraiseexcept(), fetestexcept()
Synopsis
#include <fenv.h>
Description
Use these functions to save or restore the current floating point environment in a variable.
Set excepts to the set of exceptions you want to save or restore the state of. Setting it to FE_ALL_EXCEPT
will save or restore the entire state.
Note that fexcept_t is an opaque type—you don’t know what’s in it.
excepts can be set to zero for no effect.
Return Value
Returns 0 on success or if excepts is zero.
Returns non-zero on failure.
Chapter 7. <fenv.h> Floating Point Exceptions and Environment 66
Example
This program √saves the state (before any error has happened), then deliberately causes a domain error by
trying to take −1.
After that, it restores the floating point state to before the error had occurred, thereby clearing it.
1 #include <stdio.h>
2 #include <math.h>
3 #include <fenv.h>
4
5 int main(void)
6 {
7 #pragma STDC FENV_ACCESS ON
8
9 fexcept_t flag;
10
16 if (fetestexcept(FE_INVALID))
17 printf("1: Domain error\n"); // This prints!
18 else
19 printf("1: No domain error\n");
20
23 if (fetestexcept(FE_INVALID))
24 printf("2: Domain error\n");
25 else
26 printf("2: No domain error\n"); // This prints!
27 }
7.5 feraiseexcept()
Raise a floating point exception through software
Synopsis
#include <fenv.h>
Description
This attempts to raise a floating point exception as if it had happened.
You can specify multiple exceptions to raise.
If either FE_UNDERFLOW or FE_OVERFLOW is raised, C might also raise FE_INEXACT.
Chapter 7. <fenv.h> Floating Point Exceptions and Environment 67
If either FE_UNDERFLOW or FE_OVERFLOW is raised at the same time as FE_INEXACT, then FE_UNDERFLOW or
FE_OVERFLOW will be raised before FE_INEXACT behind the scenes.
Return Value
Returns 0 if all the exceptions were raised or if excepts is 0.
Returns non-zero otherwise.
Example
This code deliberately raises a division-by-zero exception and then detects it.
1 #include <stdio.h>
2 #include <math.h>
3 #include <fenv.h>
4
5 int main(void)
6 {
7 #pragma STDC FENV_ACCESS ON
8
9 feraiseexcept(FE_DIVBYZERO);
10
11 if (fetestexcept(FE_DIVBYZERO) == FE_DIVBYZERO)
12 printf("Detected division by zero\n"); // This prints!!
13 else
14 printf("This is fine.\n");
15 }
See Also
feclearexcept(), fetestexcept()
7.6 fetestexcept()
Test to see if an exception has occurred
Synopsis
#include <fenv.h>
Description
Put the exceptions you want to test in excepts, bitwise-ORing them together.
Return Value
Returns the bitwise-OR of the exceptions that have been raised.
Chapter 7. <fenv.h> Floating Point Exceptions and Environment 68
Example
This code deliberately raises a division-by-zero exception and then detects it.
1 #include <stdio.h>
2 #include <math.h>
3 #include <fenv.h>
4
5 int main(void)
6 {
7 #pragma STDC FENV_ACCESS ON
8
9 feraiseexcept(FE_DIVBYZERO);
10
11 if (fetestexcept(FE_DIVBYZERO) == FE_DIVBYZERO)
12 printf("Detected division by zero\n"); // This prints!!
13 else
14 printf("This is fine.\n");
15 }
See Also
feclearexcept(), feraiseexcept()
Synopsis
#include <fenv.h>
int fegetround(void);
Description
Use these to get or set the rounding direction used by a variety of math functions.
Basically when a function “rounds” a number, it wants to know how to do it. By default, it does it how we
tend to expect: if the fractional part is less than 0.5, it rounds down closer to zero, otherwise up farther from
zero.
Macro Description
FE_TONEAREST Round to the nearest whole number, the default
FE_TOWARDZERO Round toward zero always
FE_DOWNWARD Round toward the next lesser whole number
FE_UPWARD Round toward the next greater whole number
Some implementations don’t support rounding. If it does, the above macros will be defined.
Chapter 7. <fenv.h> Floating Point Exceptions and Environment 69
Note that the round() function is always “to-nearest” and doesn’t pay attention to the rounding mode.
Return Value
fegetround() returns the current rounding direction, or a negative value on error.
Example
This rounds some numbers
1 #include <stdio.h>
2 #include <math.h>
3 #include <fenv.h>
4
15 return "Unknown";
16 }
17
18 int main(void)
19 {
20 #pragma STDC FENV_ACCESS ON
21
22 int rm;
23
24 rm = fegetround();
25
31 rm = fegetround();
32
Output:
FE_TONEAREST
2.000000 3.000000
FE_TOWARDZERO
2.000000 2.000000
Chapter 7. <fenv.h> Floating Point Exceptions and Environment 70
See Also
nearbyint(), nearbyintf(), nearbyintl(), rint(), rintf(), rintl(), lrint(), lrintf(),
lrintl(), llrint(), llrintf(), llrintl()
Synopsis
#include <fenv.h>
Description
You can save the environment (exceptions, rounding direction, etc.) by calling fegetenv() and restore it
with fesetenv().
Use this if you want to restore the state after a function call, i.e. hide from the caller that some floating point
exceptions or changes occurred.
Return Value
fegetenv() and fesetenv() return 0 on success, and non-zero otherwise.
Example
This example saves the environment, messes with the rounding and exceptions, then restores it. After the
environment is restored, we see that the rounding is back to default and the exception is cleared.
1 #include <stdio.h>
2 #include <math.h>
3 #include <fenv.h>
4
5 void show_status(void)
6 {
7 printf("Rounding is FE_TOWARDZERO: %d\n",
8 fegetround() == FE_TOWARDZERO);
9
14 int main(void)
15 {
16 #pragma STDC FENV_ACCESS ON
17
18 fenv_t env;
19
21
25 show_status();
26
29 show_status();
30 }
Output:
Rounding is FE_TOWARDZERO: 1
FE_DIVBYZERO is set: 1
Rounding is FE_TOWARDZERO: 0
FE_DIVBYZERO is set: 0
See Also
feholdexcept(), feupdateenv()
7.9 feholdexcept()
Save floating point state and install non-stop mode
Synopsis
#include <fenv.h>
Description
This is just like fegetenv() except that it updates the current environment to be in non-stop mode, namely
it won’t halt on any exceptions.
It remains in this state until you restore the state with fesetenv() or feupdateenv().
Return Value
Example
This example saves the environment and goes into non-stop mode, messes with the rounding and exceptions,
then restores it. After the environment is restored, we see that the rounding is back to default and the exception
is cleared. We’ll also be out of non-stop mode.
1 #include <stdio.h>
2 #include <math.h>
3 #include <fenv.h>
4
5 void show_status(void)
6 {
Chapter 7. <fenv.h> Floating Point Exceptions and Environment 72
14 int main(void)
15 {
16 #pragma STDC FENV_ACCESS ON
17
18 fenv_t env;
19
26 show_status();
27
30 show_status();
31 }
See Also
fegetenv(), fesetenv(), feupdateenv()
7.10 feupdateenv()
Restore floating point environment and apply recent exceptions
Synopsis
#include <fenv.h>
Description
This is like fesetenv() except that it modifies the passed-in environment so that it is updated with excep-
tions that have happened in the meantime.
So let’s say you had a function that might raise exceptions, but you wanted to hide those in the caller. One
option might be to:
1. Save the environment with fegetenv() or feholdexcept().
2. Do whatever you do that might raise exceptions.
3. Restore the environment with fesetenv(), thereby hiding the exceptions that happened in step 2.
Chapter 7. <fenv.h> Floating Point Exceptions and Environment 73
But that hides all exceptions. What if you just wanted to hide some of them? You could use feupdateenv()
like this:
1. Save the environment with fegetenv() or feholdexcept().
2. Do whatever you do that might raise exceptions.
3. Call feclearexcept() to clear the exceptions you want to hide from the caller.
4. Call feupdateenv() to restore the previous environment and update it with the other exceptions that
have occurred.
So it’s like a more capable way of restoring the environment than simply fegetenv()/fesetenv().
Return Value
Returns 0 on success, non-zero otherwise.
Example
This program saves state, raises some exceptions, then clears one of the exceptions, then restores and updates
the state.
1 #include <stdio.h>
2 #include <math.h>
3 #include <fenv.h>
4
5 void show_status(void)
6 {
7 printf("FE_DIVBYZERO: %d\n", fetestexcept(FE_DIVBYZERO) != 0);
8 printf("FE_INVALID : %d\n", fetestexcept(FE_INVALID) != 0);
9 printf("FE_OVERFLOW : %d\n\n", fetestexcept(FE_OVERFLOW) != 0);
10 }
11
12 int main(void)
13 {
14 #pragma STDC FENV_ACCESS ON
15
16 fenv_t env;
17
25 show_status();
26
27 feclearexcept(FE_INVALID);
28
31 show_status();
32 }
In the output, at first we have no exceptions. Then we have the three we raised. Then after we restore/update
the environment, we see the one we cleared (FE_INVALID) hasn’t been applied:
Chapter 7. <fenv.h> Floating Point Exceptions and Environment 74
FE_DIVBYZERO: 0
FE_INVALID : 0
FE_OVERFLOW : 0
FE_DIVBYZERO: 1
FE_INVALID : 1
FE_OVERFLOW : 1
FE_DIVBYZERO: 1
FE_INVALID : 0
FE_OVERFLOW : 1
See Also
fegetenv(), fesetenv(), feholdexcept(), feclearexcept()
Chapter 8
75
Chapter 8. <float.h> Floating Point Limits 76
The minimum and maximum values here are from the spec—they should what you can at least expect across
all platforms. Your super dooper machine might do better, still!
8.1 Background
The spec allows a lot of leeway when it comes to how C represents floating point numbers. This header file
spells out the limits on those numbers.
It gives a model that can describe any floating point number that I know you’re going to absolutely love. It
looks like this:
𝑝
𝑥 = 𝑠𝑏𝑒 ∑ 𝑓𝑘 𝑏−𝑘 , 𝑒𝑚𝑖𝑛 ≤ 𝑒 ≤ 𝑒𝑚𝑎𝑥
𝑘=1
where:
Variable Meaning
𝑠 Sign, −1 or 1
𝑏 Base (radix), probably 2 on your system
𝑒 Exponent
𝑝 Precision: how many base-𝑏 digits in the number
Chapter 8. <float.h> Floating Point Limits 77
Variable Meaning
𝑓𝑘 The individual digits of the number, the significand
Mode Description
-1 Indeterminable
0 Toward zero
1 To nearest
2 Toward positive infinity
3 Toward negative infinity… and beyond!
Unlike every other macro in this here header, FLT_ROUNDS might not be a constant expression.
Method Description
-1 Indeterminable
0 Evaluate all operations and constants to the precision of their respective types
1 Evaluate float and double operations as double and long double ops as long
double
2 Evaluate all operations and constants as long double
Value Description
-1 Indeterminable
0 Subnormals not supported for this type
1
https://en.wikipedia.org/wiki/Subnormal_number
Chapter 8. <float.h> Floating Point Limits 78
Value Description
1 Subnormals supported for this type
And by “use” I mean print out, have in code, read from the keyboard, etc.
You can print out that many decimal places with printf() and the %g format specifier:
1 #include <stdio.h>
2 #include <float.h>
3
4 int main(void)
5 {
6 float pi = 3.1415926535897932384626433832795028841971;
7
That’s the end, but stay tuned for the exciting conclusion of “How Many Decimal Places Can I Use?”
Because base 10 and base 2 (your typical FLT_RADIX) don’t mix very well, you can actually have more than
FLT_DIG in your float; the bits of storage go out a little farther. But these might round in a way you don’t
expect.
But if you want to convert a floating point number to base 10 and then be able to convert it back again to
the exact same floating point number, you’ll need FLT_DECIMAL_DIG digits from your float to make sure
you get those extra bits of storage represented. (And DBL_DECIMAL_DIG and LDBL_DECIMAL_DIG for those
corresponding types.)
Here’s some example output that shows how the value stored might have some extra decimal places at the
end.
1 #include <stdio.h>
2 #include <math.h>
3 #include <assert.h>
4 #include <float.h>
5
6 int main(void)
7 {
8 printf("FLT_DIG = %d\n", FLT_DIG);
9 printf("FLT_DECIMAL_DIG = %d\n\n", FLT_DECIMAL_DIG);
Chapter 8. <float.h> Floating Point Limits 79
10
And the output on my machine, starting at 0.123456 and incrementing by 0.000001 each time:
FLT_DIG = 6
FLT_DECIMAL_DIG = 9
As written: 0.123456
As stored: 0.123456001
As written: 0.123457
As stored: 0.123457
As written: 0.123458
As stored: 0.123457998
As written: 0.123459
As stored: 0.123458996
As written: 0.12346
As stored: 0.123459995
You can see that the value stored isn’t always the value we’re expecting since base-2 can’t represent all
base-10 fractions exactly. The best it can do is store more places and then round.
Also notice that even though we tried to stop the for loop before 0.123460, it actually ran including that
value since the stored version of that number was 0.123459995, which is still less than 0.123460.
Aren’t floating point numbers fun?
4 int main(void)
5 {
6 printf("FLT_RADIX: %d\n", FLT_RADIX);
7 printf("FLT_ROUNDS: %d\n", FLT_ROUNDS);
8 printf("FLT_EVAL_METHOD: %d\n", FLT_EVAL_METHOD);
9 printf("DECIMAL_DIG: %d\n\n", DECIMAL_DIG);
10
FLT_HAS_SUBNORM: 1
FLT_MANT_DIG: 24
FLT_DECIMAL_DIG: 9
FLT_DIG: 6
FLT_MIN_EXP: -125
FLT_MIN_10_EXP: -37
FLT_MAX_EXP: 128
FLT_MAX_10_EXP: 38
Chapter 8. <float.h> Floating Point Limits 81
FLT_MIN: 1.175494351e-38
FLT_MAX: 3.402823466e+38
FLT_EPSILON: 1.192092896e-07
FLT_TRUE_MIN: 1.401298464e-45
DBL_HAS_SUBNORM: 1
DBL_MANT_DIG: 53
DBL_DECIMAL_DIG: 17
DBL_DIG: 15
DBL_MIN_EXP: -1021
DBL_MIN_10_EXP: -307
DBL_MAX_EXP: 1024
DBL_MAX_10_EXP: 308
DBL_MIN: 2.22507385850720138e-308
DBL_MAX: 1.79769313486231571e+308
DBL_EPSILON: 2.22044604925031308e-16
DBL_TRUE_MIN: 4.94065645841246544e-324
LDBL_HAS_SUBNORM: 1
LDBL_MANT_DIG: 64
LDBL_DECIMAL_DIG: 21
LDBL_DIG: 18
LDBL_MIN_EXP: -16381
LDBL_MIN_10_EXP: -4931
LDBL_MAX_EXP: 16384
LDBL_MAX_10_EXP: 4932
LDBL_MIN: 3.362103143112093506263e-4932
LDBL_MAX: 1.189731495357231765021e+4932
LDBL_EPSILON: 1.084202172485504434007e-19
LDBL_TRUE_MIN: 3.645199531882474602528e-4951
sizeof(float): 4
sizeof(double): 8
sizeof(long double): 16
Chapter 9
Function Description
imaxabs() Compute the absolute value of an intmax_t
imaxdiv() Compute the quotient and remainder of intmax_ts
strtoimax() Convert strings to type intmax_t
strtoumax() Convert strings to type uintmax_t
wcstoimax() Convert wide strings to type intmax_t
wcstoumax() Convert wide strings to type uintmax_t
This header does conversions to maximum sized integers, division with maximum sized integers, and also
provides format specifiers for printf() and scanf() for a variety of types defined in <stdint.h>.
The header <stdint.h> is included by this one.
9.1 Macros
These are to help with printf() and scanf() when you use a type such as int_least16_t… what format
specifiers do you use?
Let’s start with printf()—all these macros start with PRI and then are followed by the format specifier
you’d typically use for that type. Lastly, the number of bits is added on.
For example, the format specifier for a 64-bit integer is PRId64—the d is because you usually print integers
with "%d".
An unsigned 16-bit integer could be printed with PRIu16.
These macros expand to string literals. We can take advantage of the fact that C automatically concatenates
neighboring string literals and use these specifiers like this:
1 #include <stdio.h> // for printf()
2 #include <inttypes.h>
3
4 int main(void)
5 {
6 int16_t x = 32;
7
82
Chapter 9. <inttypes.h> More Integer Conversions 83
There’s nothing magical happening on line 8, above. Indeed, if I print out the value of the macro:
printf("%s\n", PRId16);
Here’s a table of all the macros you can use for printf() format specifiers… substitute the number of bits
for N, usually 8, 16, 32, or 64.
Note again how the lowercase center letter represents the usual format specifiers you’d pass to printf(): d,
i, o, u, x, and X.
And we have a similar set of macros for scanf() for reading in these various types:
The rule is that for each type defined in <stdint.h> there will be corresponding printf() and scanf()
macros defined here.
9.2 imaxabs()
Compute the absolute value of an intmax_t
Synopsis
#include <inttypes.h>
Description
When you need the absolute value of the biggest integer type on the system, this is the function for you.
The spec notes that if the absolute value of the number cannot be represented, the behavior is undefined.
This would happen if you tried to take the absolute value of the smallest possible negative number in a
two’s-complement system.
Return Value
Returns the absolute value of the input, |𝑗|.
Example
1 #include <stdio.h>
2 #include <inttypes.h>
3
4 int main(void)
5 {
6 intmax_t j = -3490;
7
See Also
fabs()
9.3 imaxdiv()
Compute the quotient and remainder of intmax_ts
Synopsis
#include <inttypes.h>
Description
When you want to do integer division and remainder in a single operation, this function will do it for you.
It computes numer/denom and numer%denom and returns the result in a structure of type imaxdiv_t.
This structure has two imaxdiv_t fields, quot and rem, that you use to retrieve the sought-after values.
Return Value
Returns an imaxdiv_t containing the quotient and remainder of the operation.
Chapter 9. <inttypes.h> More Integer Conversions 85
Example
1 #include <stdio.h>
2 #include <inttypes.h>
3
4 int main(void)
5 {
6 intmax_t numer = INTMAX_C(3490);
7 intmax_t denom = INTMAX_C(17);
8
Output:
Quotient: 205, remainder: 5
See Also
remquo()
Synopsis
#include <inttypes.h>
Description
These work just like the strtol() family of functions, except they return an intmax_t or uintmax_t.
See the strtol() reference page for details.
Return Value
Returns the converted string as an intmax_t or uintmax_t.
If the result is out of range, the returned value will be INTMAX_MAX, INTMAX_MIN, or UINTMAX_MAX, as
appropriate. And the errno variable will be set to ERANGE.
Chapter 9. <inttypes.h> More Integer Conversions 86
Example
The following example converts a base-10 number to an intmax_t. Then it attempts to convert an invalid
base-2 number, catching the error.
1 #include <stdio.h>
2 #include <inttypes.h>
3
4 int main(void)
5 {
6 intmax_t r;
7 char *endptr;
8
12 if (*endptr != '\0')
13 printf("Invalid digit: %c\n", *endptr);
14 else
15 printf("Value is %jd\n", r);
16
20 if (*endptr != '\0')
21 printf("Invalid digit: %c\n", *endptr);
22 else
23 printf("Value is %jd\n", r);
24 }
Output:
Value is 123456789012345
Invalid digit: 2
See Also
strtol(), errno
Synopsis
#include <stddef.h> // for wchar_t
#include <inttypes.h>
Description
These work just like the wcstol() family of functions, except they return an intmax_t or uintmax_t.
See the wcstol() reference page for details.
Return Value
Returns the converted wide string as an intmax_t or uintmax_t.
If the result is out of range, the returned value will be INTMAX_MAX, INTMAX_MIN, or UINTMAX_MAX, as
appropriate. And the errno variable will be set to ERANGE.
Example
The following example converts a base-10 number to an intmax_t. Then it attempts to convert an invalid
base-2 number, catching the error.
1 #include <wchar.h>
2 #include <inttypes.h>
3
4 int main(void)
5 {
6 intmax_t r;
7 wchar_t *endptr;
8
12 if (*endptr != '\0')
13 wprintf(L"Invalid digit: %lc\n", *endptr);
14 else
15 wprintf(L"Value is %jd\n", r);
16
20 if (*endptr != '\0')
21 wprintf(L"Invalid digit: %lc\n", *endptr);
22 else
23 wprintf(L"Value is %jd\n", r);
24 }
Value is 123456789012345
Invalid digit: 2
See Also
wcstol(), errno
Chapter 10
ISO-646 is a character encoding standard that’s very similar to ASCII. But it’s missing a few notable charac-
ters, like |, ^, and ~.
Since these are operators or parts of operators in C, this header file defines a number of macros you can use in
case those characters aren’t found on your keyboard. (And also C++ can use these same alternate spellings.)
Interestingly, there is no eq for ==, and & and ! are included despite being in ISO-646.
Example usage:
1 #include <stdio.h>
2 #include <iso646.h>
3
4 int main(void)
5 {
6 int x = 12;
7 int y = 30;
8
I’ve personally never seen this file included, but I’m sure it gets used from time to time.
88
Chapter 11
Important note: the “minimum magnitude” in the table below is the minimum allowed by the spec. It’s very
likely that the values on your bad-ass system exceed those, below.
89
Chapter 11. <limits.h> Numeric Limits 90
Side benefit: you can tell at runtime if the system has signed or unsigned chars by checking to see if CHAR_MIN
is 0.
1 #include <stdio.h>
2 #include <limits.h>
3
4 int main(void)
5 {
6 printf("chars are %ssigned\n", CHAR_MIN == 0? "un": "");
7 }
4 int main(void)
5 {
6 printf("CHAR_BIT = %d\n", CHAR_BIT);
7 printf("SCHAR_MIN = %d\n", SCHAR_MIN);
8 printf("SCHAR_MAX = %d\n", SCHAR_MAX);
9 printf("UCHAR_MAX = %d\n", UCHAR_MAX);
10 printf("CHAR_MIN = %d\n", CHAR_MIN);
11 printf("CHAR_MAX = %d\n", CHAR_MAX);
12 printf("MB_LEN_MAX = %d\n", MB_LEN_MAX);
13 printf("SHRT_MIN = %d\n", SHRT_MIN);
14 printf("SHRT_MAX = %d\n", SHRT_MAX);
2
https://en.wikipedia.org/wiki/Two%27s_complement
Chapter 11. <limits.h> Numeric Limits 91
Looks like my system probably uses two’s-complement encoding for signed numbers, my chars are signed,
and my ints are 32-bit.
Chapter 12
Function Description
setlocale() Set the locale
localeconv() Get information about the current locale
The “locale” is the details of how the program should run given its physical location on the planet.
For example, in one locale, a unit of money might be printed as $123, and in another €123.
Or one locale might use ASCII encoding and another UTF-8 encoding.
By default, the program runs in the “C” locale. It has a basic set of characters with a single-byte encoding.
If you try to print UTF-8 characters in the C locale, nothing will print. You have to switch to a proper locale.
12.1 setlocale()
Set the locale
Synopsis
#include <locale.h>
Description
Sets the locale for the given category.
Category is one of the following:
Category Description
LC_ALL All of the following categories
LC_COLLATE Affects the strcoll() and strxfrm() functions
LC_CTYPE Affects the functions in <ctype.h>
92
Chapter 12. <locale.h> locale handling 93
Category Description
LC_MONETARY Affects the monetary information returned from
localeconv()
LC_NUMERIC Affects the decimal point for formatted I/O and
formatted string functions, and the monetary
information returned from localeconv()
LC_TIME Affects the strftime() and wcsftime() functions
And there are three portable things you can pass in for locale; any other string passed in is implementation-
defined and non-portable.
Locale Description
"C" Set the program to the C locale
"" (Empty string) Set the program to the native locale
of this system
NULL Change nothing; just return the current locale
Other Set the program to an implementation-defined
locale
setlocale(LC_ALL, "");
Handily, setlocale() returns the locale that was just set, so you could see what the actual locale is on your
system.
Return Value
On success, returns a pointer to the string representing the current locale. You may not modify this string,
and it might be changed by subsequent calls to setlocale().
On failure, returns NULL.
Example
Here we get the current locale. Then we set it to the native locale, and print out what that is.
1 #include <stdio.h>
2 #include <locale.h>
3
4 int main(void)
5 {
6 char *loc;
7
15
Output on my system:
Starting locale: C
Native locale: en_US.UTF-8
Note that my native locale (on a Linux box) might be different from what you see.
Nevertheless, I can explicitly set it on my system without a problem, or to any other locale I have installed:
13 loc = setlocale(LC_ALL, "en_US.UTF-8"); // Non-portable
See Also
localeconv(), strcoll(), strxfrm(), strftime(), wcsftime(), printf(), scanf(), <ctype.h>
12.2 localeconv()
Get information about the current locale
Synopsis
#include <locale.h>
Description
This function just returns a pointer to a struct lconv, but is still a bit of a powerhouse.
The returned structure contains tons of information about the locale. Here are the fields of struct lconv
and their meanings.
First, some conventions. In the field names, below, a _p_ means “positive”, and _n_ means “negative”, and
int_ means “international”. Though a lot of these are type char or char*, most (or the strings they point
to) are actually treated as integers1 .
Before we go further, know that CHAR_MAX (from <limits.h>) is the maximum value that can be held in a
char. And that many of the following char values use that to indicate the value isn’t available in the given
locale.
Field Description
char *mon_decimal_point Decimal pointer character for money, e.g. ".".
char *mon_thousands_sep Thousands separator character for money, e.g. ",".
char *mon_grouping Grouping description for money (see below).
char *positive_sign Positive sign for money, e.g. "+" or "".
char *negative_sign Negative sign for money, e.g. "-".
char *currency_symbol Currency symbol, e.g. "$".
1
Remember that char is just a byte-sized integer.
Chapter 12. <locale.h> locale handling 95
Field Description
char frac_digits When printing monetary amounts, how many digits to print past the
decimal point, e.g. 2.
char p_cs_precedes 1 if the currency_symbol comes before the value for a non-negative
monetary amount, 0 if after.
char n_cs_precedes 1 if the currency_symbol comes before the value for a negative
monetary amount, 0 if after.
char p_sep_by_space Determines the separation of the currency symbol from the value for
non-negative amounts (see below).
char n_sep_by_space Determines the separation of the currency symbol from the value for
negative amounts (see below).
char p_sign_posn Determines the positive_sign position for non-negative values.
char p_sign_posn Determines the positive_sign position for negative values.
char *int_curr_symbol International currency symbol, e.g. "USD ".
char int_frac_digits International value for frac_digits.
char int_p_cs_precedes International value for p_cs_precedes.
char int_n_cs_precedes International value for n_cs_precedes.
char int_p_sep_by_space International value for p_sep_by_space.
char int_n_sep_by_space International value for n_sep_by_space.
char int_p_sign_posn International value for p_sign_posn.
char int_n_sign_posn International value for n_sign_posn.
Even though many of these have char type, the value stored within is meant to be accessed as an integer.
All the sep_by_space variants deal with spacing around the currency sign. Valid values are:
Value Description
0 No space between currency symbol and value.
1 Separate the currency symbol (and sign, if any) from the value with a space.
2 Separate the sign symbol from the currency symbol (if adjacent) with a space,
otherwise separate the sign symbol from the value with a space.
Value Description
0 Put parens around the value and the currency symbol.
1 Put the sign string in front of the currency symbol and value.
2 Put the sign string after the currency symbol and value.
3 Put the sign string directly in front of the currency symbol.
4 Put the sign string directly behind the currency symbol.
Return Value
Returns a pointer to the structure containing the locale information.
The program may not modify this structure.
Subsequent calls to localeconv() may overwrite this structure, as might calls to setlocale() with
LC_ALL, LC_MONETARY, or LC_NUMERIC.
Chapter 12. <locale.h> locale handling 96
Example
Here’s a program to print the locale information for the native locale.
1 #include <stdio.h>
2 #include <locale.h>
3 #include <limits.h> // for CHAR_MAX
4
9 while (!done) {
10 if (*mg == CHAR_MAX)
11 printf("CHAR_MAX ");
12 else
13 printf("%c ", *mg + '0');
14 done = *mg == CHAR_MAX || *mg == 0;
15 mg++;
16 }
17 }
18
19 int main(void)
20 {
21 setlocale(LC_ALL, "");
22
Output on my system:
Chapter 12. <locale.h> locale handling 97
mon_decimal_point : .
mon_thousands_sep : ,
mon_grouping : 3 3 0
positive_sign :
negative_sign : -
currency_symbol : $
frac_digits : 2
p_cs_precedes : 1
n_cs_precedes : 1
p_sep_by_space : 0
n_sep_by_space : 0
p_sign_posn : 1
p_sign_posn : 1
int_curr_symbol : USD
int_frac_digits : 2
int_p_cs_precedes : 1
int_n_cs_precedes : 1
int_p_sep_by_space: 1
int_n_sep_by_space: 1
int_p_sign_posn : 1
int_n_sign_posn : 1
See Also
setlocale()
Chapter 13
<math.h> Mathematics
Many of the following functions have float and long double variants as described below (e.g. pow(),
powf(), powl()). The float and long double variants are omitted from the following table to keep your
eyeballs from melting out.
Function Description
acos() Calculate the arc cosine of a number.
acosh() Compute arc hyperbolic cosine.
asin() Calculate the arc sine of a number.
asinh() Compute arc hyperbolic sine.
atan(), atan2() Calculate the arc tangent of a number.
atanh() Compute the arc hyperbolic tangent.
cbrt() Compute the cube root.
ceil() Ceiling—return the next whole number not smaller than the given number.
copysign() Copy the sign of one value into another.
cos() Calculate the cosine of a number.
cosh() Compute the hyperbolic cosine.
erf() Compute the error function of the given value.
erfc() Compute the complementary error function of a value.
exp() Compute 𝑒 raised to a power.
exp2() Compute 2 to a power.
expm1() Compute 𝑒𝑥 − 1.
fabs() Compute the absolute value.
fdim() Return the positive difference between two numbers clamped at 0.
floor() Compute the largest whole number not larger than the given value.
fma() Floating (AKA “Fast”) multiply and add.
fmax(), fmin() Return the maximum or minimum of two numbers.
fmod() Compute the floating point remainder.
fpclassify() Return the classification of a given floating point number.
frexp() Break a number into its fraction part and exponent (as a power of 2).
hypot() Compute the length of the hypotenuse of a triangle.
ilogb() Return the exponent of a floating point number.
isfinite() True if the number is not infinite or NaN.
isgreater() True if one argument is greater than another.
isgreatereequal() True if one argument is greater than or equal to another.
isinf() True if the number is infinite.
isless() True if one argument is less than another.
islesseequal() True if one argument is less than or equal to another.
98
Chapter 13. <math.h> Mathematics 99
Function Description
islessgreater() Test if a floating point number is less than or greater than another.
isnan() True if the number is Not-a-Number.
isnormal() True if the number is normal.
isunordered() Macro returns true if either floating point argument is NaN.
ldexp() Multiply a number by an integral power of 2.
lgamma() Compute the natural logarithm of the absolute value of Γ(𝑥).
log() Compute the natural logarithm.
log10() Compute the log-base-10 of a number.
log2() Compute the base-2 logarithm of a number.
logb() Extract the exponent of a number given FLT_RADIX.
log1p() Compute the natural logarithm of a number plus 1.
lrint() Returns x rounded in the current rounding direction as an integer.
lround(), llround() Round a number in the good old-fashioned way, returning an integer.
modf() Extract the integral and fractional parts of a number.
nan() Return NAN.
nearbyint() Rounds a value in the current rounding direction.
nextafter() Get the next (or previous) representable floating point value.
nexttoward() Get the next (or previous) representable floating point value.
pow() Compute a value raised to a power.
remainder() Compute the remainder IEC 60559-style.
remquo() Compute the remainder and (some of the) quotient.
rint() Rounds a value in the current rounding direction.
round() Round a number in the good old-fashioned way.
scalbn(), scalbln() Efficiently compute 𝑥 × 𝑟𝑛 , where 𝑟 is FLT_RADIX.
signbit() Return the sign of a number.
sin() Calculate the sine of a number.
sqrt() Calculate the square root of a number.
tan() Calculate the tangent of a number.
tanh() Compute the hyperbolic tangent.
tgamma() Compute the gamma function, Γ(𝑥).
trunc() Truncate the fractional part off a floating point value.
It’s your favorite subject: Mathematics! Hello, I’m Doctor Math, and I’ll be making math FUN and EASY!
[vomiting sounds]
Ok, I know math isn’t the grandest thing for some of you out there, but these are merely functions that quickly
and easily do math you either know, want, or just don’t care about. That pretty much covers it.
Remember that parameters are given values as if you assigned into them. So if you pass a double to powf(),
it’ll choose the closest float it can to hold the double. If the double doesn’t fit, undefined behavior happens.
The idea with these types is they can represent the most efficient way of storing numbers for maximum speed.
Their actual types vary by implementation, but can be determined by the value of the FLT_EVAL_METHOD
macro.
For all defined values of FLT_EVAL_METHOD, float_t is the least-precise type used for all floating calcula-
tions.
Defined in <float.h> is FLT_RADIX: the number base used by floating point numbers. This is commonly
2, but could be anything.
Now, the C math library can do a couple things when these errors occur:
• Set errno to some value, or…
• Raise a floating point exception.
Your system might vary on what happens. You can check it by looking at the value of the variable
math_errhandling. It will be equivalent to one of the following1 :
math_errhandling Description
MATH_ERRNO The system uses errno for math errors.
MATH_ERREXCEPT The system uses exceptions for math errors.
MATH_ERRNO | MATH_ERREXCEPT The system does both! (That’s a bitwise-OR!)
If you do this at global scope, it stays at whatever state you set it to until you change it.
If you do it at block scope, it reverts to the value outside the block when the block ends.
The initial value of the FP_CONTRACT pragma varies from system to system.
13.6 fpclassify()
Return the classification of a given floating point number.
1
Though the system defines MATH_ERRNO as 1 and MATH_ERREXCEPT as 2, it’s best to always use their symbolic names. Just in case.
Chapter 13. <math.h> Mathematics 102
Synopsis
#include <math.h>
Description
What kind of entity does this floating point number represent? What are the options?
We’re used to floating point numbers being regular old things like 3.14 or 3490.0001.
But floating point numbers can also represent things like infinity. Or Not-A-Number (NAN). This function
will let you know which type of floating point number the argument is.
This is a macro, so you can use it with float, double, long double or anything similar.
Return Value
Returns one of these macros depending on the argument’s classification:
Classification Description
FP_INFINITE Number is infinite.
FP_NAN Number is Not-A-Number (NAN).
FP_NORMAL Just a regular number.
FP_SUBNORMAL Number is a sub-normal number.
FP_ZERO Number is zero.
A discussion of subnormal numbers is beyond the scope of the guide, and is something that most devs go
their whole lives without dealing with. In a nutshell, it’s a way to represent really small numbers that might
normally round down to zero. If you want to know more, see the Wikipedia page on denormal numbers2 .
Example
Print various number classifications.
1 #include <stdio.h>
2 #include <math.h>
3
14 return "unknown";
15 }
16
17 int main(void)
2
https://en.wikipedia.org/wiki/Denormal_number
Chapter 13. <math.h> Mathematics 103
18 {
19 printf(" 1.23: %s\n", get_classification(1.23));
20 printf(" 0.0: %s\n", get_classification(0.0));
21 printf("sqrt(-1): %s\n", get_classification(sqrt(-1)));
22 printf("1/tan(0): %s\n", get_classification(1/tan(0)));
23 printf(" 1e-310: %s\n", get_classification(1e-310)); // very small!
24 }
Output3 :
1.23: normal
0.0: zero
sqrt(-1): not a number
1/tan(0): infinity
1e-310: subnormal
See Also
isfinite(), isinf(), isnan(), isnormal(), signbit()
Synopsis
#include <math.h>
Description
These are helper macros to fpclassify(). Bring macros, they work on any floating point type.
Macro Description
isfinite() True if the number is not infinite or NaN.
isinf() True if the number is infinite.
isnan() True if the number is Not-a-Number.
isnormal() True if the number is normal.
For more superficial discussion on normal and subnormal numbers, see fpclassify().
3
This is on my system. Some systems will have different points at which numbers become subnormal, or they might not support
subnormal values at all.
Chapter 13. <math.h> Mathematics 104
Return Value
Returns non-zero for true, and zero for false.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf(" isfinite(1.23): %d\n", isfinite(1.23)); // 1
7 printf(" isinf(1/tan(0)): %d\n", isinf(1/tan(0))); // 1
8 printf(" isnan(sqrt(-1)): %d\n", isnan(sqrt(-1))); // 1
9 printf("isnormal(1e-310): %d\n", isnormal(1e-310)); // 0
10 }
See Also
fpclassify(), signbit(),
13.8 signbit()
Return the sign of a number.
Synopsis
#include <math.h>
Description
This macro takes any floating point number and returns a value indicating the sign of the number, positive
or negative.
Return Value
Returns 1 if the sign is negative, otherwise 0.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("%d\n", signbit(3490.0)); // 0
7 printf("%d\n", signbit(-37.0)); // 1
8 }
Chapter 13. <math.h> Mathematics 105
See Also
fpclassify(), isfinite(), isinf(), isnan(), isnormal(), copysign()
Synopsis
#include <math.h>
Description
Calculates the arc cosine of a number in radians. (That is, the value whose cosine is x.) The number must be
in the range -1.0 to 1.0.
For those of you who don’t remember, radians are another way of measuring an angle, just like degrees. To
convert from degrees to radians or the other way around, use the following code:
pi = 3.14159265358979;
degrees = radians * 180 / pi;
radians = degrees * pi / 180;
Return Value
Returns the arc cosine of x, unless x is out of range. In that case, errno will be set to EDOM and the return
value will be NaN. The variants return different types.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 double acosx;
7 long double ldacosx;
8
9 acosx = acos(0.2);
10 ldacosx = acosl(0.3L);
11
12 printf("%f\n", acosx);
13 printf("%Lf\n", ldacosx);
14 }
Chapter 13. <math.h> Mathematics 106
See Also
asin(), atan(), atan2(), cos()
Synopsis
#include <math.h>
Description
Calculates the arc sine of a number in radians. (That is, the value whose sine is x.) The number must be in
the range -1.0 to 1.0.
For those of you who don’t remember, radians are another way of measuring an angle, just like degrees. To
convert from degrees to radians or the other way around, use the following code:
pi = 3.14159265358979;
degrees = radians * 180 / pi;
radians = degrees * pi / 180;
Return Value
Returns the arc sine of x, unless x is out of range. In that case, errno will be set to EDOM and the return
value will be NaN. The variants return different types.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 double asinx;
7 long double ldasinx;
8
9 asinx = asin(0.2);
10 ldasinx = asinl(0.3L);
11
12 printf("%f\n", asinx);
13 printf("%Lf\n", ldasinx);
14 }
Chapter 13. <math.h> Mathematics 107
See Also
acos(), atan(), atan2(), sin()
Synopsis
#include <math.h>
Description
Calculates the arc tangent of a number in radians. (That is, the value whose tangent is x.)
The atan2() variants are pretty much the same as using atan() with y/x as the argument…except that
atan2() will use those values to determine the correct quadrant of the result.
For those of you who don’t remember, radians are another way of measuring an angle, just like degrees. To
convert from degrees to radians or the other way around, use the following code:
pi = 3.14159265358979;
degrees = radians * 180 / pi;
radians = degrees * pi / 180;
Return Value
The atan() functions return the arc tangent of x, which will be between PI/2 and -PI/2. The atan2()
functions return an angle between PI and -PI.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 double atanx;
7 long double ldatanx;
8
9 atanx = atan(0.7);
10 ldatanx = atanl(0.3L);
11
Chapter 13. <math.h> Mathematics 108
12 printf("%f\n", atanx);
13 printf("%Lf\n", ldatanx);
14
18 printf("%f\n", atanx);
19 printf("%Lf\n", ldatanx);
20 }
See Also
tan(), asin(), atan()
Synopsis
#include <math.h>
double cos(double x)
float cosf(float x)
long double cosl(long double x)
Description
Calculates the cosine of the value x, where x is in radians.
For those of you who don’t remember, radians are another way of measuring an angle, just like degrees. To
convert from degrees to radians or the other way around, use the following code:
pi = 3.14159265358979;
degrees = radians * 180 / pi;
radians = degrees * pi / 180;
Return Value
Returns the cosine of x. The variants return different types.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 double cosx;
7 long double ldcosx;
8
Chapter 13. <math.h> Mathematics 109
12 printf("%f\n", cosx);
13 printf("%Lf\n", ldcosx);
14 }
See Also
sin(), tan(), acos()
Synopsis
#include <math.h>
Description
Calculates the sine of the value x, where x is in radians.
For those of you who don’t remember, radians are another way of measuring an angle, just like degrees. To
convert from degrees to radians or the other way around, use the following code:
pi = 3.14159265358979;
degrees = radians * 180 / pi;
radians = degrees * pi / 180;
Return Value
Returns the sine of x. The variants return different types.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 double sinx;
7 long double ldsinx;
8
12 printf("%f\n", sinx);
13 printf("%Lf\n", ldsinx);
14 }
See Also
cos(), tan(), asin()
Synopsis
#include <math.h>
double tan(double x)
float tanf(float x)
long double tanl(long double x)
Description
Calculates the tangent of the value x, where x is in radians.
For those of you who don’t remember, radians are another way of measuring an angle, just like degrees. To
convert from degrees to radians or the other way around, use the following code:
pi = 3.14159265358979;
degrees = radians * 180 / pi;
radians = degrees * pi / 180;
Return Value
Returns the tangent of x. The variants return different types.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 double tanx;
7 long double ldtanx;
8
12 printf("%f\n", tanx);
13 printf("%Lf\n", ldtanx);
14 }
Chapter 13. <math.h> Mathematics 111
See Also
sin(), cos(), atan(), atan2()
Synopsis
#include <math.h>
Description
Trig lovers can rejoice! C has arc hyperbolic cosine!
These functions return the nonnegative acosh of x, which must be greater than or equal to 1.
Return Value
Returns the arc hyperbolic cosince in the range [0, +∞].
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("acosh 1.8 = %f\n", acosh(1.8)); // 1.192911
7 }
See Also
asinh()
Synopsis
Chapter 13. <math.h> Mathematics 112
#include <math.h>
Description
Trig lovers can rejoice! C has arc hyperbolic sine!
These functions return the asinh of x.
Return Value
Returns the arc hyperbolic sine.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("asinh 1.8 = %f\n", asinh(1.8)); // 1.350441
7 }
See Also
acosh()
Synopsis
#include <math.h>
Description
These functions compute the arc hyperbolic tangent of x, which must be in the range [−1, +1]. Passing
exactly −1 or +1 might result in a pole error.
Chapter 13. <math.h> Mathematics 113
Return Value
Returns the arc hyperbolic tangent of x.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("atanh 0.5 = %f\n", atanh(0.5)); // 0.549306
7 }
See Also
acosh(), asinh()
Synopsis
#include <math.h>
Description
These functions predictably compute the hyperbolic cosine of x. A range error might occur if x is too large.
Return Value
Returns the hyperbolic cosine of x.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("cosh 0.5 = %f\n", cosh(0.5)); // 1.127626
7 }
Chapter 13. <math.h> Mathematics 114
See Also
sinh(), tanh()
Synopsis
#include <math.h>
Description
These functions predictably compute the hyperbolic sine of x. A range error might occur if x is too large.
Return Value
Returns the hyperbolic sine of x.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("sinh 0.5 = %f\n", sinh(0.5)); // 0.521095
7 }
See Also
sinh(), tanh()
Synopsis
#include <math.h>
Chapter 13. <math.h> Mathematics 115
Description
These functions predictably compute the hyperbolic tangent of x.
Mercifully, this is the last trig-related man page I’m going to write.
Return Value
Returns the hyperbolic tangent of x.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("tanh 0.5 = %f\n", tanh(0.5)); // 0.462117
7 }
See Also
cosh(), sinh()
Synopsis
#include <math.h>
Description
Compute 𝑒𝑥 where 𝑒 is Euler’s number4 .
The number 𝑒 is named after Leonard Euler, born April 15, 1707, who is responsible, among other things,
for making this reference page longer than it needed to be.
4
https://en.wikipedia.org/wiki/E_(mathematical_constant)
Chapter 13. <math.h> Mathematics 116
Return Value
Returns 𝑒𝑥 .
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("exp(1) = %f\n", exp(1)); // 2.718282
7 printf("exp(2) = %f\n", exp(2)); // 7.389056
8 }
See Also
exp2(), expm1(), pow(), log()
Synopsis
#include <math.h>
Description
These functions raise 2 to a power. Very exciting, since computers are all about twos-to-powers!
These are likely to be faster than using pow() to do the same thing.
They support fractional exponents, as well.
A range error occurs if x is too large.
Return Value
exp2() returns 2𝑥 .
Example
1 #include <stdio.h>
2 #include <math.h>
3
Chapter 13. <math.h> Mathematics 117
4 int main(void)
5 {
6 printf("2^3 = %f\n", exp2(3)); // 2^3 = 8.000000
7 printf("2^8 = %f\n", exp2(8)); // 2^8 = 256.000000
8 printf("2^0.5 = %f\n", exp2(0.5)); // 2^0.5 = 1.414214
9 }
See Also
exp(), pow()
Synopsis
#include <math.h>
Description
This is just like exp() except—plot twist!–it computes that result minus one.
For more discussion about what 𝑒 is, see the exp() man page.
If x is giant, a range error might occur.
For small values of x near zero, expm1(x) might be more accurate than computing exp(x)-1.
Return Value
Returns 𝑒𝑥 − 1.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("%f\n", expm1(2.34)); // 9.381237
7 }
Chapter 13. <math.h> Mathematics 118
See Also
exp()
Synopsis
#include <math.h>
Description
If you have a floating point number, you can break it into its fractional part and exponent part (as a power of
2).
For example, if you have the number 1234.56, this can be represented as a multiple of a power of 2 like so:
1234.56 = 0.6028125 × 211
And you can use this function to get the 0.6028125 and 11 parts of that equation.
As for why, I have a simple answer: I don’t know. I can’t find a use. K&R2 and everyone else I can find just
says how to use it, but not why you might want to.
The C99 Rationale document says:
The functions frexp, ldexp, and modf are primitives used by the remainder of the library.
There was some sentiment for dropping them for the same reasons that ecvt, fcvt, and gcvt
were dropped, but their adherents rescued them for general use. Their use is problematic: on
non-binary architectures, ldexp may lose precision and frexp may be inefficient.
So there you have it. If you need it.
Return Value
frexp() returns the fractional part of value in the range 0.5 (inclusive) to 1 (exclusive), or 0. And it stores
the exponent power-of-2 in the variable pointed to by exp.
If you pass in zero, the return value and the variable exp points to are both zero.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
Chapter 13. <math.h> Mathematics 119
6 double frac;
7 int expt;
8
Output:
1234.56 = 0.6028125 x 2^11
See Also
ldexp(), ilogb(), modf()
Synopsis
#include <math.h>
Description
This gives you the exponent of the given number… it’s a little weird, because the exponent depends on the
value of FLT_RADIX. Now, this is very often 2—but no guarantees!
It actually returns log𝑟 |𝑥| where 𝑟 is FLT_RADIX.
Domain or range errors might occur for invalid values of x, or for return values that are outside the range of
the return type.
Return Value
The exponent of the absolute value of the given number, depending on FLT_RADIX.
Specifically log𝑟 |𝑥| where 𝑟 is FLT_RADIX.
If you pass in 0, it’ll return FP_ILOGB0.
If you pass in infinity, it’ll return INT_MAX.
If you pass in NaN, it’ll return FP_ILOGBNAN.
The spec goes on to say that the value of FP_ILOGB0 will be either INT_MIN or -INT_MAX. And the value of
FP_ILOGBNAN shall be either INT_MAX or INT_MIN, if that’s useful in any way.
Chapter 13. <math.h> Mathematics 120
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("%d\n", ilogb(257)); // 8
7 printf("%d\n", ilogb(256)); // 8
8 printf("%d\n", ilogb(255)); // 7
9 }
See Also
frexp(), logb()
Synopsis
#include <math.h>
Description
These functions multiply the given number x by 2 raised to the exp power.
Return Value
Returns 𝑥 × 2𝑒𝑥𝑝 .
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("1 x 2^10 = %f\n", ldexp(1, 10));
7 printf("5.67 x 2^7 = %f\n", ldexp(5.67, 7));
8 }
Output:
Chapter 13. <math.h> Mathematics 121
1 x 2^10 = 1024.000000
5.67 x 2^7 = 725.760000
See Also
exp()
Synopsis
#include <math.h>
Description
Natural logarithms! And there was much rejoycing.
These compute the base-𝑒 logarithm of a number, log𝑒 𝑥, ln 𝑥.
In other words, for a given 𝑥, solves 𝑥 = 𝑒𝑦 for 𝑦.
Return Value
The base-𝑒 logarithm of the given value, log𝑒 𝑥, ln 𝑥.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 const double e = 2.718281828459045;
7
See Also
exp(), log10(), log1p()
Chapter 13. <math.h> Mathematics 122
Synopsis
#include <math.h>
Description
Just when you thought you might have to use Laws of Logarithms to compute this, here’s a function coming
out of the blue to save you.
These compute the base-10 logarithm of a number, log10 𝑥.
In other words, for a given 𝑥, solves 𝑥 = 10𝑦 for 𝑦.
Return Value
Returns the log base-10 of x, log10 𝑥.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("%f\n", log10(3490.2)); // 3.542850
7 printf("%f\n", log10(10)); // 1.000000
8 }
See Also
pow(), log()
Synopsis
#include <math.h>
Description
This computes log𝑒 (1 + 𝑥), ln(1 + 𝑥).
This works just like calling:
log(1 + x)
Return Value
Returns log𝑒 (1 + 𝑥), ln(1 + 𝑥).
Example
Compute some big and small logarithm values to see the difference between log1p() and log():
1 #include <stdio.h>
2 #include <float.h> // for LDBL_DECIMAL_DIG
3 #include <math.h>
4
5 int main(void)
6 {
7 printf("Big log1p() : %.*Lf\n", LDBL_DECIMAL_DIG-1, log1pl(9));
8 printf("Big log() : %.*Lf\n", LDBL_DECIMAL_DIG-1, logl(1 + 9));
9
Output on my system:
Big log1p() : 2.30258509299404568403
Big log() : 2.30258509299404568403
Small log1p(): 0.00995033085316808305
Small log() : 0.00995033085316809164
See Also
log()
Synopsis
#include <math.h>
Description
Wow! Were you thinking we were done with the logarithm functions? We’re only getting started!
This one computes log2 𝑥. That is, computes 𝑦 that satisfies 𝑥 = 2𝑦 .
Love me those powers of 2!
Return Value
Returns the base-2 logarithm of the given value, log2 𝑥.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("%f\n", log2(3490.2)); // 11.769094
7 printf("%f\n", log2(256)); // 8.000000
8 }
See Also
log()
Synopsis
#include <math.h>
Description
This function returns the whole number portion of the exponent of the number with radix FLT_RADIX, namely
the whole number portion log𝑟 |𝑥| where 𝑟 is FLT_RADIX. Fractional numbers are truncated.
If the number is subnormal5 , logb() treats it as if it were normalized.
If x is 0, there could be a domain error or pole error.
Return Value
This function returns the whole number portion of log𝑟 |𝑥| where 𝑟 is FLT_RADIX.
Example
1 #include <stdio.h>
2 #include <float.h> // For FLT_RADIX
3 #include <math.h>
4
5 int main(void)
6 {
7 printf("FLT_RADIX = %d\n", FLT_RADIX);
8 printf("%f\n", logb(3490.2));
9 printf("%f\n", logb(256));
10 }
Output:
FLT_RADIX = 2
11.000000
8.000000
See Also
ilogb()
Synopsis
#include <math.h>
5
https://en.wikipedia.org/wiki/Denormal_number
Chapter 13. <math.h> Mathematics 126
Description
If you have a floating point number, like 123.456, this function will extract the integral part (123.0) and the
fractional part (0.456). It’s total coincidence that this is exactly the plot for the latest Jason Statham action
spectacular.
Both the integral part and fractional parts keep the sign of the passed in value.
The integral part is stored in the address pointed to by iptr.
See the note in frexp() regarding why this is in the library.
Return Value
These functions return the fractional part of the number. The integral part is stored in the address pointed to
by iptr. Both the integral and fractional parts preserve the sign of the passed-in value.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 void print_parts(double x)
5 {
6 double i, f;
7
8 f = modf(x, &i);
9
15 int main(void)
16 {
17 print_parts(123.456);
18 print_parts(-123.456);
19 }
Output:
Entire number : 123.456000
Integral part : 123.000000
Fractional part: 0.456000
See Also
frexp()
Chapter 13. <math.h> Mathematics 127
Synopsis
#include <math.h>
Description
These functions efficiently compute 𝑥 × 𝑟𝑛 , where 𝑟 is FLT_RADIX.
If FLT_RADIX happens to be 2 (no guarantees!), then this works like exp2().
The name of this function should have an obvious meaning to you. Clearly they all start with the prefix
“scalb” which means…
…OK, I confess! I have no idea what it means. My searches are futile!
But let’s look at the suffixes:
Suffix Meaning
n scalbn()—exponent n is an int
nf scalbnf()—float version of scalbn()
nl scalbnl()—long double version of scalbn()
ln scalbln()—exponent n is a long int
lnf scalblnf()—float version of scalbln()
lnl scalblnl()—long double version of scalbln()
So while I’m still in the dark about “scalb”, at least I have that part down.
A range error might occur for large values.
Return Value
Returns 𝑥 × 𝑟𝑛 , where 𝑟 is FLT_RADIX.
Example
Chapter 13. <math.h> Mathematics 128
1 #include <stdio.h>
2 #include <math.h>
3 #include <float.h>
4
5 int main(void)
6 {
7 printf("FLT_RADIX = %d\n\n", FLT_RADIX);
8 printf("scalbn(3, 8) = %f\n", scalbn(2, 8));
9 printf("scalbnf(10.2, 20) = %f\n", scalbnf(10.2, 20));
10 }
Output on my system:
FLT_RADIX = 2
scalbn(3, 8) = 512.000000
scalbn(10.2, 20.7) = 10695475.200000
See Also
exp2(), pow()
Synopsis
#include <math.h>
Description
√
Computes the cube root of x, 𝑥1/3 , 3
𝑥.
Return Value
√
Returns the cube root of x, 𝑥1/3 , 3
𝑥.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
Chapter 13. <math.h> Mathematics 129
Output:
cbrt(1729.03) = 12.002384
See Also
sqrt(), pow()
Synopsis
#include <math.h>
Description
These functions straightforwardly return the absolute value of x, that is |𝑥|.
If you’re rusty on your absolute values, all it means is that the result will be positive, even if x is negative.
It’s just strips negative signs off.
Return Value
Returns the absolute value of x, |𝑥|.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("fabs(3490.0) = %f\n", fabs(3490.0)); // 3490.000000
7 printf("fabs(-3490.0) = %f\n", fabs(3490.0)); // 3490.000000
8 }
See Also
abs(), copysign(), imaxabs()
Chapter 13. <math.h> Mathematics 130
Synopsis
#include <math.h>
Description
Pythagorean Theorem6 fans rejoice! This is the function you’ve been waiting for!
If you know the lengths of the two sides of a right triangle, x and y, you can compute the length of the
hypotenuse (the longest, diagonal side) with this function.
In particular, it computes the square root of the sum of the squares of the sides: √𝑥2 + 𝑦 2 .
Return Value
Returns the lenght of the hypotenuse of a right triangle with side lengths x and y: √𝑥2 + 𝑦2 .
Example
1 printf("%f\n", hypot(3, 4)); // 5.000000
See Also
sqrt()
Synopsis
#include <math.h>
6
https://en.wikipedia.org/wiki/Pythagorean_theorem
Chapter 13. <math.h> Mathematics 131
Description
Computes x raised to the yth power: 𝑥𝑦 .
These arguments can be fractional.
Return Value
Returns x raised to the yth power: 𝑥𝑦 .
A domain error can occur if:
• x is a finite negative number and y is a finite non-integer
• x is zero and y is zero.
A domain error or pole error can occur if x is zero and y is negative.
A range error can occur for large values.
Example
1 printf("%f\n", pow(3, 4)); // 3^4 = 81.000000
2 printf("%f\n", pow(2, 0.5)); // sqrt 2 = 1.414214
See Also
exp(), exp2(), sqrt(), cbrt()
13.38 sqrt()
Calculate the square root of a number.
Synopsis
#include <math.h>
Description
√
Computes the square root of a number: 𝑥. To those of you who don’t know what a square root is, I’m not
going to explain. Suffice it to say, the square root of a number delivers a value that when squared (multiplied
by itself) results in the original number.
Ok, fine—I did explain it after all, but only because I wanted to show off. It’s not like I’m giving you
examples or anything, such as the square root of nine is three, because when you multiply three by three you
get nine, or anything like that. No examples. I hate examples!
And I suppose you wanted some actual practical information here as well. You can see the usual trio of func-
tions here—they all compute square root, but they take different types as arguments. Pretty straightforward,
really.
Chapter 13. <math.h> Mathematics 132
Return Value
√
Returns (and I know this must be something of a surprise to you) the square root of x: 𝑥.
Example
1 // example usage of sqrt()
2
11 dx = x2 - x1;
12 dy = y2 - y1;
13 printf("distance between points (x1, y1) and (x2, y2): %.2f\n",
14 sqrt(dx*dx + dy*dy));
See Also
hypot(), pow()
Synopsis
#include <math.h>
Description
These functions compute the error function7 of a value.
7
https://en.wikipedia.org/wiki/Error_function
Chapter 13. <math.h> Mathematics 133
Return Value
Returns the error function of x:
𝑥
2 2
√ ∫ 𝑒−𝑡 𝑑𝑡
𝜋 0
Example
1 for (float i = -2; i <= 2; i += 0.5)
2 printf("% .1f: %f\n", i, erf(i));
Output:
-2.0: -0.995322
-1.5: -0.966105
-1.0: -0.842701
-0.5: -0.520500
0.0: 0.000000
0.5: 0.520500
1.0: 0.842701
1.5: 0.966105
2.0: 0.995322
See Also
erfc()
Synopsis
#include <math.h>
Description
These functions compute the complementary error function8 of a value.
This is the same as:
1 - erf(x)
Return Value
Returns 1 - erf(x), namely:
∞
2 2
√ ∫ 𝑒−𝑡 𝑑𝑡
𝜋 𝑥
Example
1 for (float i = -2; i <= 2; i += 0.5)
2 printf("% .1f: %f\n", i, erfc(i));
Output:
-2.0: 1.995322
-1.5: 1.966105
-1.0: 1.842701
-0.5: 1.520500
0.0: 1.000000
0.5: 0.479500
1.0: 0.157299
1.5: 0.033895
2.0: 0.004678
See Also
erf()
Synopsis
#include <math.h>
Description
Compute the natural log of the absolute value of gamma9 x, log𝑒 |Γ(𝑥)|.
A range error can occur if x is too large.
A pole error can occur is x is non-positive.
9
https://en.wikipedia.org/wiki/Gamma_function
Chapter 13. <math.h> Mathematics 135
Return Value
Returns log𝑒 |Γ(𝑥)|.
Example
1 for (float i = 0.5; i <= 4; i += 0.5)
2 printf("%.1f: %f\n", i, lgamma(i));
Output:
0.5: 0.572365
1.0: 0.000000
1.5: -0.120782
2.0: 0.000000
2.5: 0.284683
3.0: 0.693147
3.5: 1.200974
4.0: 1.791759
See Also
tgamma()
Synopsis
#include <math.h>
Description
Computes the gamma function10 of x, Γ(𝑥).
A domain or pole error might occur if x is non-positive.
A range error might occur if x is too large or too small.
Return Value
Returns the gamma function of x, Γ(𝑥).
10
https://en.wikipedia.org/wiki/Gamma_function
Chapter 13. <math.h> Mathematics 136
Example
1 for (float i = 0.5; i <= 4; i += 0.5)
2 printf("%.1f: %f\n", i, tgamma(i));
Output:
0.5: 1.772454
1.0: 1.000000
1.5: 0.886227
2.0: 1.000000
2.5: 1.329340
3.0: 2.000000
3.5: 3.323351
4.0: 6.000000
See Also
lgamma()
Synopsis
#include <math.h>
Description
Returns the ceiling of the x: ⌈𝑥⌉.
This is the next whole number not smaller than x.
Beware this minor dragon: it’s not just “rounding up”. Well, it is for positive numbers, but negative numbers
effectively round toward zero. (Because the ceiling function is headed for the next largest whole number and
−4 is larger than −5.)
Return Value
Returns the next largest whole number larger than x.
Example
Notice for the negative numbers it heads toward zero, i.e. toward the next largest whole number—just like
the positives head toward the next largest whole number.
Chapter 13. <math.h> Mathematics 137
See Also
floor(), round()
Synopsis
#include <math.h>
double floor(double x);
float floorf(float x);
long double floorl(long double x);
Description
Returns the floor of the value: ⌊𝑥⌋. This is the opposite of ceil().
This is the largest whole number that is not greater than x.
For positive numbers, this is like rounding down: 4.5 becomes 4.0.
For negative numbers, it’s like rounding up: -3.6 becomes -4.0.
In both cases, those results are the largest whole number not bigger than the given number.
Return Value
Returns the largest whole number not greater than x: ⌊𝑥⌋.
Example
Note how the negative numbers effectively round away from zero, unlike the positives.
1 printf("%f\n", floor(4.0)); // 4.000000
2 printf("%f\n", floor(4.1)); // 4.000000
3 printf("%f\n", floor(-2.0)); // -2.000000
4 printf("%f\n", floor(-2.1)); // -3.000000
5 printf("%f\n", floor(-3.1)); // -4.000000
See Also
ceil(), round()
Chapter 13. <math.h> Mathematics 138
Synopsis
#include <math.h>
Description
This function rounds x to the nearest integer in the current rounding direction.
The rounding direction can be set with fesetround() in <fenv.h>.
nearbyint() won’t raise the “inexact” floating point exception.
Return Value
Returns x rounded in the current rounding direction.
Example
1 #include <stdio.h>
2 #include <math.h>
3 #include <fenv.h>
4
5 int main(void)
6 {
7 #pragma STDC FENV_ACCESS ON // If supported
8
See Also
rint(), lrint(), round(), fesetround(), fegetround()
Chapter 13. <math.h> Mathematics 139
Synopsis
#include <math.h>
Description
This works just like nearbyint() except that is can raise the “inexact” floating point exception.
Return Value
Returns x rounded in the current rounding direction.
Example
1 #include <stdio.h>
2 #include <math.h>
3 #include <fenv.h>
4
5 int main(void)
6 {
7 #pragma STDC FENV_ACCESS ON
8
9 fesetround(FE_TONEAREST);
10
14 fesetround(FE_TOWARDZERO);
15
See Also
nearbyint(), lrint(), round(), fesetround(), fegetround()
Synopsis
#include <math.h>
Description
Round a floating point number in the current rounding direction, but this time return an integer intead of a
float. You know, just to mix it up.
These come in two variants:
• lrint()—returns long int
• llrint()—returns long long int
If the result doesn’t fit in the return type, a domain or range error might occur.
Return Value
The value of x rounded to an integer in the current rounding direction.
Example
1 #include <stdio.h>
2 #include <math.h>
3 #include <fenv.h>
4
5 int main(void)
6 {
7 #pragma STDC FENV_ACCESS ON
8
9 fesetround(FE_TONEAREST);
10
11 printf("%ld\n", lrint(3.14)); // 3
12 printf("%ld\n", lrint(3.74)); // 4
13
14 fesetround(FE_TOWARDZERO);
15
16 printf("%ld\n", lrint(1.99)); // 1
17 printf("%ld\n", lrint(-1.99)); // -1
18 }
See Also
nearbyint(), rint(), round(), fesetround(), fegetround()
Chapter 13. <math.h> Mathematics 141
Synopsis
#include <math.h>
Description
Rounds a number to the nearest whole value.
In case of halfsies, rounds away from zero (i.e. “round up” in magnitude).
The current rounding direction’s Jedi mind tricks don’t work on this function.
Return Value
The rounded value of x.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("%f\n", round(3.14)); // 3.000000
7 printf("%f\n", round(3.5)); // 4.000000
8
See Also
lround(), nearbyint(), rint(), lrint(), trunc()
Synopsis
#include <math.h>
Description
These are just like round() except they return integers.
Halfway values round away from zero, e.g. 1.5 rounds to 2 and −1.5 rounds to −2.
The functions are grouped by return type:
• lround()—returns a long int
• llround()—returns a long long int
If the rounded value can’t fit in the return type, a domain or range error can occur.
Return Value
Returns the rounded value of x as an integer.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("%ld\n", lround(3.14)); // 3
7 printf("%ld\n", lround(3.5)); // 4
8
9 printf("%ld\n", lround(-1.5)); // -2
10 printf("%ld\n", lround(-1.14)); // -1
11 }
See Also
round(), nearbyint(), rint(), lrint(), trunc()
Synopsis
#include <math.h>
Description
These functions just drop the fractional part of a floating point number. Boom.
In other words, they always round toward zero.
Return Value
Returns the truncated floating point number.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("%f\n", trunc(3.14)); // 3.000000
7 printf("%f\n", trunc(3.8)); // 3.000000
8
See Also
round(), lround(), nearbyint(), rint(), lrint()
Synopsis
#include <math.h>
Description
Returns the remainder of 𝑥𝑦 . The result will have the same sign as x.
Under the hood, the computation performed is:
x - trunc(x / y) * y
Return Value
𝑥
Returns the remainder of 𝑦 with the same sign as x.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("%f\n", fmod(-9.2, 5.1)); // -4.100000
7 printf("%f\n", fmod(9.2, 5.1)); // 4.100000
8 }
See Also
remainder()
Synopsis
#include <math.h>
Description
This is similar to fmod(), but not quite the same. fmod() is probably what you’re after if you’re expecting
remainders to wrap around like an odometer.
The C spec quotes IEC 60559 on how this works:
When 𝑦 ≠ 0, the remainder 𝑟 = 𝑥 REM 𝑦 is defined regardless of the rounding mode by
the mathematical relation 𝑟 = 𝑥 − 𝑛𝑦 , where 𝑛 is the integer nearest the exact value of 𝑥/𝑦;
whenever |𝑛 − 𝑥/𝑦| = 1/2, then 𝑛 is even. If 𝑟 = 0, its sign shall be that of 𝑥.
Chapter 13. <math.h> Mathematics 145
In other words, the range of the function runs from -y/2 to y/2. Contrasted to fmod() that runs from 0.0
to y, remainder()’s output is just shifted down half a y.
And zero-remainder-anything is 0.
Except if y is zero, the function might return zero or a domain error might occur.
Return Value
The IEC 60559 result of x-remainder-y.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("%f\n", remainder(3.7, 4)); // -0.300000
7 printf("%f\n", remainder(4.3, 4)); // 0.300000
8 }
See Also
fmod(), remquo()
Synopsis
#include <math.h>
Description
This is a funky little thing.
Chapter 13. <math.h> Mathematics 146
First of all, the return value is the remainder, the same as the remainder() function, so check that out.
And the quotient comes back in the quo pointer.
Or at least some of it does. You’ll get at least 3 bits worth of the quotient.
But why?
So a couple things.
One is that the quotient of some very large floating point numbers can easily be far too gigantic to fit in even
a long long unsigned int. So some of it might very well need to be lopped off, anyway.
But at 3 bits? How’s that even useful? That only gets you from 0 to 7!
The C99 Rationale document states:
The remquo functions are intended for implementing argument reductions which can exploit a
few low-order bits of the quotient. Note that 𝑥 may be so large in magnitude relative to 𝑦 that
an exact representation of the quotient is not practical.
So… implementing argument reductions… which can exploit a few low-order bits… Ooookay.
CPPReference has this to say11 on the matter, which is spoken so well, I will quote wholesale:
This function is useful when implementing periodic functions with the period exactly repre-
sentable as a floating-point value: when calculating sin(𝜋𝑥) for a very large x, calling sin
directly may result in a large error, but if the function argument is first reduced with remquo,
the low-order bits of the quotient may be used to determine the sign and the octant of the result
within the period, while the remainder may be used to calculate the value with high precision.
And there you have it. If you have another example that works for you… congratulations! :)
Return Value
Returns the same as remainder: The IEC 60559 result of x-remainder-y.
In addition, at least the lowest 3 bits of the quotient will be stored in quo with the same sign as x/y.
Example
There’s a great cos() example at CPPReference12 that covers a genuine use case.
But instead of stealing it, I’ll just post a simple example here and you can visit their site for a real one.
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 int quo;
7 double rem;
8
11
https://en.cppreference.com/w/c/numeric/math/remquo
12
https://en.cppreference.com/w/c/numeric/math/remquo
Chapter 13. <math.h> Mathematics 147
See Also
remainder(), imaxdiv()
Synopsis
#include <math.h>
Description
These functions return a number that has the magnitude of x and the sign of y. You can use them to coerce
the sign to that of another value.
Neither x nor y are modified, of course. The return value holds the result.
Return Value
Returns a value with the magnitude of x and the sign of y.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 double x = 34.9;
7 double y = -999.9;
8 double z = 123.4;
9
See Also
signbit()
Chapter 13. <math.h> Mathematics 148
Synopsis
#include <math.h>
Description
These functions return a quiet NaN13 . It is produced as if calling strtod() with "NAN" (or a variant thereof)
as an argument.
tagp points to a string which could be several things, including empty. The contents of the string determine
which variant of NaN might get returned depending on the implementation.
Which version of NaN? Did you even know it was possible to get this far into the weeds with something that
wasn’t a number?
Case 1 in which you pass in an empty string, in which case these are the same:
nan("");
strtod("NAN()", NULL);
Case 2 in which the string contains only digits 0-9, letters a-z, letters A-Z, and/or underscore:
nan("goats");
strtod("NAN(goats)", NULL);
And Case 3, in which the string contains anything else and is ignored:
nan("!");
strtod("NAN", NULL);
As for what strtod() does with those values in parens, see the [strtod()] reference page. Spoiler: it’s
implementation-defined.
Return Value
Returns the requested quiet NaN, or 0 if such things aren’t supported by your system.
Example
1 #include <stdio.h>
2 #include <math.h>
3
13
A quiet NaN is one that doesn’t raise any exceptions.
Chapter 13. <math.h> Mathematics 149
4 int main(void)
5 {
6 printf("%f\n", nan("")); // nan
7 printf("%f\n", nan("goats")); // nan
8 printf("%f\n", nan("!")); // nan
9 }
See Also
strtod()
Synopsis
#include <math.h>
Description
As you probably know, floating point numbers can’t represent every possible real number. There are limits.
And, as such, there exists a “next” and “previous” number after or before any floating point number.
These functions return the next (or previous) representable number. That is, no floating point numbers exist
between the given number and the next one.
The way it figures it out is it works from x in the direction of y, answering the question of “what is the next
representable number from x as we head toward y.
Return Value
Returns the next representable floating point value from x in the direction of y.
If x equals y, returns y. And also x, I suppose.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("%.*f\n", DBL_DECIMAL_DIG, nextafter(0.5, 1.0));
Chapter 13. <math.h> Mathematics 150
Output on my system:
0.50000000000000011
0.34899999999999992
See Also
nexttoward()
Synopsis
include <math.h>
Description
These functions are the same as nextafter() except the second parameter is always long double.
Return Value
Returns the same as nextafter() except if x equals y, returns y cast to the function’s return type.
Example
1 #include <stdio.h>
2 #include <float.h>
3 #include <math.h>
4
5 int main(void)
6 {
7 printf("%.*f\n", DBL_DECIMAL_DIG, nexttoward(0.5, 1.0));
8 printf("%.*f\n", DBL_DECIMAL_DIG, nexttoward(0.349, 0.0));
9 }
Output on my system:
0.50000000000000011
0.34899999999999992
Chapter 13. <math.h> Mathematics 151
See Also
nextafter()
Synopsis
#include <math.h>
Description
The positive difference between x and y is the difference… except if the difference is less than 0, it’s clamped
to 0.
These functions might throw a range error.
Return Value
Returns the difference of x-y if the difference is greater than 0. Otherwise it returns 0.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("%f\n", fdim(10.0, 3.0)); // 7.000000
7 printf("%f\n", fdim(3.0, 10.0)); // 0.000000, clamped
8 }
Synopsis
#include <math.h>
Description
Straightforwardly, these functions return the minimum or maximum of two given numbers.
If one of the numbers is NaN, the functions return the non-NaN number. If both arguments are NaN, the
functions return NaN.
Return Value
Returns the minimum or maximum values, with NaN handled as mentioned above.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("%f\n", fmin(10.0, 3.0)); // 3.000000
7 printf("%f\n", fmax(3.0, 10.0)); // 10.000000
8 }
Synopsis
#include <math.h>
Description
This performs the operation (𝑥 × 𝑦) + 𝑧 , but does so in a nifty way. It does the computation as if it had
infinite precision, and then rounds the final result to the final data type according to the current rounding
Chapter 13. <math.h> Mathematics 153
mode.
Contrast to if you’d do the math yourself, where it would have rounded each step of the way, potentially.
Also some architectures have a CPU instruction to do exactly this calculation, so it can do it super quick. (If
it doesn’t, it’s considerably slower.)
You can tell if your CPU supports the fast version by checking that the macro FP_FAST_FMA is set to 1. (The
float and long variants of fma() can be tested with FP_FAST_FMAF and FP_FAST_FMAL, respectively.)
Return Value
Returns (x * y) + z.
Example
1 printf("%f\n", fma(1.0, 2.0, 3.0)); // 5.000000
Synopsis
#include <math.h>
Description
These macros compare floating point numbers. Being macros, we can pass in any floating point type.
You might think you can already do that with just regular comparison operators—and you’d be right!
One one exception: the comparison operators raise the “invalid” floating exception if one or more of the
operands is NaN. These macros do not.
Note that you must only pass floating point types into these functions. Passing an integer or any other type
is undefined behavior.
Return Value
isgreater() returns the result of x > y.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("%d\n", isgreater(10.0, 3.0)); // 1
7 printf("%d\n", isgreaterequal(10.0, 10.0)); // 1
8 printf("%d\n", isless(10.0, 3.0)); // 0
9 printf("%d\n", islessequal(10.0, 3.0)); // 0
10 }
See Also
islessgreater(), isunordered()
13.62 islessgreater()
Test if a floating point number is less than or greater than another.
Synopsis
#include <math.h>
Description
This macro is similar to isgreater() and all those, except it made the section name too long if I included
it up there. So it gets its own spot.
This returns true if 𝑥 < 𝑦 or 𝑥 > 𝑦 .
Even though it’s a macro, we can rest assured that x and y are only evaluated once.
And even if x or y are NaN, this will not throw an “invalid” exception, unlike the normal comparison opera-
tors.
If you pass in a non-floating type, the behavior is undefined.
Return Value
Returns (x < y) || (x > y).
Example
1 #include <stdio.h>
2 #include <math.h>
3
Chapter 13. <math.h> Mathematics 155
4 int main(void)
5 {
6 printf("%d\n", islessgreater(10.0, 3.0)); // 1
7 printf("%d\n", islessgreater(10.0, 30.0)); // 1
8 printf("%d\n", islessgreater(10.0, 10.0)); // 0
9 }
See Also
isgreater(), isgreaterequal(), isless(), islessequal(), isunordered()
13.63 isunordered()
Macro returns true if either floating point argument is NaN.
Synopsis
#include <math.h>
Description
The spec writes:
The isunordered macro determines whether its arguments are unordered.
See? Told you C was easy!
It does also elaborate that the arguments are unordered if one or both of them are NaN.
Return Value
This macro returns true if one or both of the arguments are NaN.
Example
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void)
5 {
6 printf("%d\n", isunordered(1.0, 2.0)); // 0
7 printf("%d\n", isunordered(1.0, sqrt(-1))); // 1
8 printf("%d\n", isunordered(NAN, 30.0)); // 1
9 printf("%d\n", isunordered(NAN, NAN)); // 1
10 }
See Also
isgreater(), isgreaterequal(), isless(), islessequal(), islessgreater()
Chapter 14
These functions enable you to rewind the call stack to an earlier point, with a bunch of gotchas. It is rarely
used.
Function Description
longjmp() Return to the previously-placed bookmark
setjmp() Bookmark this place to return to later
There’s also a new opaque type, jmp_buf, that holds all the information needed to pull off this magic trick.
If you want your automatic local variables to be correct after a call to longjmp(). declare them as volatile
where you called setjmp().
14.1 setjmp()
Save this location as one to return to later
Synopsis
#include <setjmp.h>
Description
This is how you save your position so you can longjmp() back it, later. Think of it as setting up a warp
destination for later use.
Basically, you call this, giving it an env it can fill in with all the information it needs to come back here later.
This env is one you’ll pass to longjmp() later when you want to teleport back here.
And the really funky part is this can return two different ways:
1. It can return 0 from the call where you set up the jump destination.
2. If can return non-zero when you actually warp back here as the result of a call to longjmp().
156
Chapter 14. <setjmp.h> Non-local Goto 157
What you can do is check the return value to see which case has occurred.
You’re only allowed to call setjmp() in a limited number of circumstances.
1. As a standalone expression:
setjmp(env);
You can also cast it to (void) if you really wanted to do such a thing.
2. As the complete controlling expression in an if or switch.
if (setjmp(env)) { ... }
But not this as it’s not the complete controlling expression in this case:
if (x == 2 && setjmp()) { ... } // Undefined behavior
Return Value
This one is funky. It returns one of two things:
Returns 0 if this was the call to setjmp() to set it up.
Returns non-zero if being here was the result of a call to longjmp(). (Namely, it returns the value passed
into the longjmp() function.)
Example
Here’s a function that calls setjmp() to set things up (where it returns 0), then calls a couple levels deep
into functions, and finally short-circuits the return path by longjmp()ing back to the place where setjmp()
was called, earlier. This time, it passes 3490 as a value, which setjmp() returns.
1 #include <stdio.h>
2 #include <setjmp.h>
3
4 jmp_buf env;
5
6 void depth2(void)
7 {
8 printf("Entering depth 2\n");
9 longjmp(env, 3490); // Jump back to setjmp()!!
10 printf("Leaving depth 2\n"); // This won't happen
11 }
12
13 void depth1(void)
Chapter 14. <setjmp.h> Non-local Goto 158
14 {
15 printf("Entering depth 1\n");
16 depth2();
17 printf("Leaving depth 1\n"); // This won't happen
18 }
19
20 int main(void)
21 {
22 switch (setjmp(env)) {
23 case 0:
24 printf("Calling into functions, setjmp() returned 0\n");
25 depth1();
26 printf("Returned from functions\n"); // This won't happen
27 break;
28
29 case 3490:
30 printf("Bailed back to main, setjmp() returned 3490\n");
31 break;
32 }
33 }
Notice that the second printf() in case 0 didn’t run; it got jumped over by longjmp()!
See Also
longjmp()
14.2 longjmp()
Return to the previous setjmp() location
Synopsis
#include <setjmp.h>
Description
This returns to a previous call to setjmp() back in the call history. setjmp() will return the val passed
into longjmp().
The env passed to setjmp() should be the same one you pass into longjmp().
There are a bunch of potential issues with doing this, so you’ll want to be careful that you avoid undefined
behavior by not doing the following:
Chapter 14. <setjmp.h> Non-local Goto 159
Though longjmp() attempts to restore the machine to the state at the setjmp(), including local variables,
there are some things that aren’t brought back to life:
• Non-volatile local variables that might have changed
• Floating point status flags
• Open files
• Any other component of the abstract machine
Return Value
This one is also funky in that it is one of the few functions in C that never returns!
Example
Here’s a function that calls setjmp() to set things up (where it returns 0), then calls a couple levels deep
into functions, and finally short-circuits the return path by longjmp()ing back to the place where setjmp()
was called, earlier. This time, it passes 3490 as a value, which setjmp() returns.
1 #include <stdio.h>
2 #include <setjmp.h>
3
4 jmp_buf env;
5
6 void depth2(void)
7 {
8 printf("Entering depth 2\n");
9 longjmp(env, 3490); // Jump back to setjmp()!!
10 printf("Leaving depth 2\n"); // This won't happen
11 }
12
13 void depth1(void)
14 {
15 printf("Entering depth 1\n");
16 depth2();
17 printf("Leaving depth 1\n"); // This won't happen
18 }
19
20 int main(void)
21 {
22 switch (setjmp(env)) {
23 case 0:
24 printf("Calling into functions, setjmp() returned 0\n");
25 depth1();
26 printf("Returned from functions\n"); // This won't happen
27 break;
Chapter 14. <setjmp.h> Non-local Goto 160
28
29 case 3490:
30 printf("Bailed back to main, setjmp() returned 3490\n");
31 break;
32 }
33 }
Notice that the second printf() in case 0 didn’t run; it got jumped over by longjmp()!
See Also
setjmp()
Chapter 15
Function Description
signal() Set a signal handler for a given signal
raise() Cause a signal to be raised
15.1 signal()
Set a signal handler for a given signal
Synopsis
#include <signal.h>
Description
How’s that for a function declaration?
Let’s ignore it for a moment and just talk about what this function does.
When a signal is raised, something is going to happen. This function lets you decide to do one of these things
when the signal is raised:
• Ignore the signal
1
https://man.archlinux.org/man/sigaction.2.en
161
Chapter 15. <signal.h> signal handling 162
Signal Description
SIGABRT Raised when abort() is called
SIGFPE Floating-point arithmetic exception
SIGILL CPU tried to execute an illegal instruction
SIGINT Interrupt signal, as if CTRL-C were pressed
SIGSEGV Segmention Violation: attempted to access restricted memory
SIGTERM Termination request2
So that’s the first bit when you call signal()—tell it the signal in question:
signal(SIGINT, ...
func Description
SIG_DFL Perform the default action on this signal
SIG_IGN Ignore this signal
For example:
signal(SIGTERM, SIG_DFL); // Default action on SIGTERM
signal(SIGINT, SIG_IGN); // Ignore SIGINT
But what if you want to have your own handler do something instead of the default or ignoring it? You can
pass in your own function to be called. That’s what the crazy function signature is partially about. It’s saying
that the argument can be a pointer to a function that takes an int argument and returns void.
So if you wanted to call your handler, you could have code like this:
int handler(int sig)
{
// Handle the signal
}
int main(void)
{
signal(SIGINT, handler);
If the signal is not due to abort() or raise(), you’re only allowed to call these functions from the standard
library (though the spec doesn’t prohibit calling other non-library functions):
• abort()
• _Exit()
• quick_exit()
• Functions in <stdatomic.h> when the atomic arguments are lock-free
• signal() with a first argument equivalent to the argument that was passed into the handler
In addition, if the signal was not due to abort() or raise(), the handler can’t access any object with static
or thread-storage duration unless it’s lock-free.
An exception is that you can assign to (but not read from!) a variable of type volatile sig_atomic_t.
It’s up to the implementation, but the signal handler might be reset to SIG_DFL just before the handler is
called.
It’s undefined behavior to call signal() in a multithreaded program.
It’s undefined behavior to return from the handler for SIGFPE, SIGILL, SIGSEGV, or any implementation-
defined value. You must exit.
The implementation might or might not prevent other signals from arising while in the signal handler.
Return Value
On success, signal() returns a pointer to the previous signal handler set by a call to signal() for that
particular signal number. If you haven’t called it set, returns SIG_DFL.
On failure, SIG_ERR is returned and errno is set to a positive value.
Example
Here’s a program that causes SIGINT to be ignored. Commonly you trigger this signal by hitting CTRL-C.
1 #include <stdio.h>
2 #include <signal.h>
3
4 int main(void)
5 {
6 signal(SIGINT, SIG_IGN);
7
Output:
You can't hit CTRL-C to exit this program. Try it!
This program sets the signal handler, then raises the signal. The signal handler fires.
1 #include <stdio.h>
2 #include <signal.h>
3
5 {
6 // Undefined behavior to call printf() if this handler was not
7 // as the result of a raise(), i.e. if you hit CTRL-C.
8
14 signal(sig, handler);
15 }
16
17 int main(void)
18 {
19 signal(SIGINT, handler);
20
21 raise(SIGINT);
22 raise(SIGINT);
23 raise(SIGINT);
24 }
Output:
Got signal 2!
Got signal 2!
Got signal 2!
This example catches SIGINT but then sets a flag to 1. Then the main loop sees the flag and exits.
1 #include <stdio.h>
2 #include <signal.h>
3
4 volatile sig_atomic_t x;
5
11 int main(void)
12 {
13 signal(SIGINT, handler);
14
See Also
raise(), abort()
Chapter 15. <signal.h> signal handling 165
15.2 raise()
Cause a signal to be raised
Synopsis
#include <signal.h>
Description
Causes the signal handler for the signal sig to be called. If the handler is SIG_DFL or SIG_IGN, then the
default action or no action happens.
raise() returns after the signal handler has finished running.
Interestingly, if you cause a signal to happen with raise(), you can call library functions from within the
signal handler without causing undefined behavior. I’m not sure how this fact is practically useful, though.
Return Value
Returns 0 on success. Nonzero otherwise.
Example
This program sets the signal handler, then raises the signal. The signal handler fires.
1 #include <stdio.h>
2 #include <signal.h>
3
14 signal(sig, handler);
15 }
16
17 int main(void)
18 {
19 signal(SIGINT, handler);
20
21 raise(SIGINT);
22 raise(SIGINT);
23 raise(SIGINT);
24 }
Output:
Chapter 15. <signal.h> signal handling 166
Got signal 2!
Got signal 2!
Got signal 2!
See Also
signal()
Chapter 16
If you’re coding up something low-level like a memory allocator that interfaces with your OS, you might
need this header file. But most C devs go their careers without using it.
Alignment1 is all about multiples of addresses on which objects can be stored. Can you store this at any
address? Or must it be a starting address that’s divisible by 2? Or 8? Or 16?
Name Description
alignas() Specify alignment, expands to _Alignas
alignof() Get alignment, expands to _Alignof
Quick note: alignments greater than that of max_align_t are known as overalignments and are
implementation-defined.
Synopsis
#include <stdalign.h>
alignas(type-name)
alignas(constant-expression)
_Alignas(type-name)
_Alignas(constant-expression)
1
https://en.wikipedia.org/wiki/Data_structure_alignment
167
Chapter 16. <stdalign.h> Macros for Alignment 168
Description
Use this alignment specifier to force the alignment of particular variables. For instance, we can declare c to
be char, but aligned as if it were an int:
char alignas(int) c;
You can put a constant integer expression in there, as well. The compiler will probably impose limits on
what these values can be. Small powers of 2 (1, 2, 4, 8, and 16) are generally safe bets.
char alignas(8) c; // align on 8-byte boundaries
For convenience, you can also specify 0 if you want the default alignment (as if you hadn’t said alignas()
at all):
char alignas(0) c; // use default alignment for this type
Example
1 #include <stdalign.h>
2 #include <stdio.h> // for printf()
3 #include <stddef.h> // for max_align_t
4
5 int main(void)
6 {
7 int i, j;
8 char alignas(max_align_t) a, b;
9 char alignas(int) c, d;
10 char e, f;
11
Output on my system follows. Notice the difference between the pairs of values.
• i and j, both ints, are aligned on 4-byte boundaries.
• a and b have been forced to the boundary of the type max_align_t, which is every 16 bytes on my
system.
• c and d have been forced to the same alignment as int, which is 4 bytes, just like with i and j.
• e and f do not have an alignment specified, so they were stored with their default alignment of 1 byte.
i: 0x7ffee7dfb4cc <-- difference of 4 bytes
j: 0x7ffee7dfb4c8
See Also
alignof, max_align_t
Synopsis
#include <stdalign.h>
alignof(type-name)
_Alignof(type-name)
Description
This evaluates to a value of type size_t that gives the alignment of a particular type on your system.
Return Value
Returns the alignment value, i.e. the address of the beginning of the given type of object must begin on an
address boundary divisible by this number.
Example
Print out the alignments of a variety of different types.
1 #include <stdalign.h>
2 #include <stdio.h> // for printf()
3 #include <stddef.h> // for max_align_t
4
5 struct t {
6 int a;
7 char b;
8 float c;
9 };
10
11 int main(void)
12 {
13 printf("char : %zu\n", alignof(char));
14 printf("short : %zu\n", alignof(short));
15 printf("int : %zu\n", alignof(int));
16 printf("long : %zu\n", alignof(long));
17 printf("long long : %zu\n", alignof(long long));
18 printf("double : %zu\n", alignof(double));
19 printf("long double: %zu\n", alignof(long double));
Chapter 16. <stdalign.h> Macros for Alignment 170
Output on my system:
char : 1
short : 2
int : 4
long : 8
long long : 8
double : 8
long double: 16
struct t : 16
max_align_t: 16
See Also
alignas, max_align_t
Chapter 17
Macro Description
va_arg() Get the next variable argument
va_copy() Copy a va_list and the work done so far
va_end() Signify we’re done processing variable arguments
va_start() Initialize a va_list to start variable argument processing
This header file is what allows you to write functions that take a variable number of arguments.
In addition to the macros, you get a new type that helps C keep track of where it is in the variable-number-of-
arguments-processing: va_list. This type is opaque, and you’ll be passing it around to the various macros
to help get at the arguments.
Note that every variadic function requires at least one non-variable parameter. You need this to kick off
processing with va_start().
17.1 va_arg()
Get the next variable argument
Synopsis
#include <stdarg.h>
Description
If you have a variable argument list you’ve initialized with va_start(), pass it to this one along with the
type of argument you’re trying to get, e.g.
int x = va_arg(args, int);
float y = va_arg(args, float);
171
Chapter 17. <stdarg.h> Variable Arguments 172
Return Value
Evaluates to the value and type of the next variable argument.
Example
Here’s a demo that adds together an arbitrary number of integers. The first argument is the number of integers
to add together. We’ll make use of that to figure out how many times we have to call va_arg().
1 #include <stdio.h>
2 #include <stdarg.h>
3
14 total += n;
15 }
16
19 return total;
20 }
21
22 int main(void)
23 {
24 printf("%d\n", add(4, 6, 2, -4, 17)); // 6 + 2 - 4 + 17 = 21
25 printf("%d\n", add(2, 22, 44)); // 22 + 44 = 66
26 }
See Also
va_start(), va_end()
17.2 va_copy()
Copy a va_list and the work done so far
Synopsis
#include <stdarg.h>
Description
The main intended use of this is to save your state partway through processing variable arguments so you
can scan ahead and then rewind back to the save point.
You pass in a src va_list and it copies it to dest.
If you’ve already called this once for a particular dest, you can’t call it (or va_start()) again with the
same dest unless you call va_end() on that dest first.
va_copy(dest, src);
va_copy(dest, src2); // BAD!
va_copy(dest, src);
va_start(dest, var); // BAD!
va_copy(dest, src);
va_end(dest);
va_copy(dest, src2); // OK!
va_copy(dest, src);
va_end(dest);
va_start(dest, var); // OK!
Return Value
Returns nothing.
Example
Here’s an example where we’re adding together all the variable arguments, but then we want to go back and
add on all the numbers past the first two, for example if the arguments are:
10 20 30 40
First we add them all for 100, and then we add on everything from the third number on, so add on 30+40 for
a total of 170.
We’ll do this by saving our place in the variable argument processing with va_copy and then using that later
to reprocess the trailing arguments.
(And yes, I know there’s a mathematical way to do this without all the rewinding, but I’m having an heck of
a time coming up with a good example!)
1 #include <stdio.h>
2 #include <stdarg.h>
3
4 // Add all the numbers together, but then add on all the numbers
5 // past the second one again.
6 int contrived_adder(int count, ...)
7 {
8 if (count < 3) return 0; // OK, I'm being lazy. You got me.
9
10 int total = 0;
11
14 va_start(args, count);
Chapter 17. <stdarg.h> Variable Arguments 174
15
21 if (i == 2)
22 va_copy(mid_args, args);
23
29 // But now let's start with mid_args and add all those on:
30 for (int i = 0; i < count - 2; i++)
31 total += va_arg(mid_args, int);
32
35 return total;
36 }
37
38 int main(void)
39 {
40 // 10+20+30 + 30 == 90
41 printf("%d\n", contrived_adder(3, 10, 20, 30));
42
See Also
va_start(), va_arg(), va_end()
17.3 va_end()
Signify we’re done processing variable arguments
Synopsis
#include <stdarg.h>
Description
After you’ve va_start()ed or va_copy’d a new va_list, you must call va_end() with it before it goes
out of scope.
Chapter 17. <stdarg.h> Variable Arguments 175
You also have to do this if you’re going to call va_start() or va_copy() again on a variable you’ve already
done that to.
Them’s the rules if you want to avoid undefined behavior.
But just think of it as cleanup. You called va_start(), so you’ll call va_end() when you’re done.
Return Value
Returns nothing.
Example
Here’s a demo that adds together an arbitrary number of integers. The first argument is the number of integers
to add together. We’ll make use of that to figure out how many times we have to call va_arg().
1 #include <stdio.h>
2 #include <stdarg.h>
3
14 total += n;
15 }
16
19 return total;
20 }
21
22 int main(void)
23 {
24 printf("%d\n", add(4, 6, 2, -4, 17)); // 6 + 2 - 4 + 17 = 21
25 printf("%d\n", add(2, 22, 44)); // 22 + 44 = 66
26 }
See Also
va_start(), va_copy()
17.4 va_start()
Initialize a va_list to start variable argument processing
Chapter 17. <stdarg.h> Variable Arguments 176
Synopsis
#include <stdarg.h>
Description
You’ve declared a variable of type va_list to keep track of the variable argument processing… now how
to initialize it so you can start calling va_arg() to get those arguments?
va_start() to the rescue!
What you do is pass in your va_list, here shown as parameter ap. Just pass the list, not a pointer to it.
Then for the second argument to va_start(), you give the name of the parameter that you want to start
processing arguments after. This must be the parameter right before the ... in the argument list.
If you’ve already called va_start() on a particular va_list and you want to call va_start() on it again,
you must call va_end() first!
Return Value
Returns nothing!
Example
Here’s a demo that adds together an arbitrary number of integers. The first argument is the number of integers
to add together. We’ll make use of that to figure out how many times we have to call va_arg().
1 #include <stdio.h>
2 #include <stdarg.h>
3
14 total += n;
15 }
16
19 return total;
20 }
21
22 int main(void)
23 {
24 printf("%d\n", add(4, 6, 2, -4, 17)); // 6 + 2 - 4 + 17 = 21
25 printf("%d\n", add(2, 22, 44)); // 22 + 44 = 66
26 }
Chapter 17. <stdarg.h> Variable Arguments 177
See Also
va_arg(), va_end()
Chapter 18
<stdatomic.h> Atomic-Related
Functions
Function Description
atomic_compare_exchange_strong_explicit() Atomic compare and exchange, strong, explicit
atomic_compare_exchange_strong() Atomic compare and exchange, strong
atomic_compare_exchange_weak_explicit() Atomic compare and exchange, weak, explicit
atomic_compare_exchange_weak() Atomic compare and exchange, weak
atomic_exchange_explicit() Replace a value in an atomic object, explicit
atomic_exchange() Replace a value in an atomic object
atomic_fetch_add_explicit() Atomically add to an atomic integer, explicit
atomic_fetch_add() Atomically add to an atomic integer
atomic_fetch_and_explicit() Atomically bitwise-AND an atomic integer, explicit
atomic_fetch_and() Atomically bitwise-AND an atomic integer
atomic_fetch_or_explicit() Atomically bitwise-OR an atomic integer, explicit
atomic_fetch_or() Atomically bitwise-OR an atomic integer
atomic_fetch_sub_explicit() Atomically subtract from an atomic integer, explicit
atomic_fetch_sub() Atomically subtract from an atomic integer
atomic_fetch_xor_explicit() Atomically bitwise-XOR an atomic integer, explicit
atomic_fetch_xor() Atomically bitwise-XOR an atomic integer
atomic_flag_clear_explicit() Clear an atomic flag, explicit
atomic_flag_clear() Clear an atomic flag
atomic_flag_test_and_set_explicit() Test and set an atomic flag, explicit
atomic_flag_test_and_set() Test and set an atomic flag
atomic_init() Initialize an atomic variable
atomic_is_lock_free() Determine if an atomic type is lock free
atomic_load_explicit() Return a value from an atomic variable, explicit
atomic_load() Return a value from an atomic variable
atomic_signal_fence() Fence for intra-thread signal handlers
atomic_store_explicit() Store a value in an atomic variable, explicit
atomic_store() Store a value in an atomic variable
atomic_thread_fence() Set up a fence
ATOMIC_VAR_INIT() Create an initializer for an atomic variable
kill_dependency() End a dependency chain
You might need to add -latomic to your compilation command line on Unix-like operating systems.
178
Chapter 18. <stdatomic.h> Atomic-Related Functions 179
You can make your own additional types with the _Atomic type qualifier:
_Atomic double x;
They can be used at compile time with #if. They apply to both signed and unsigned types.
Value Meaning
0 Never lock-free.
1 Sometimes lock-free1 .
2 Always lock-free.
memory_order Description
memory_order_seq_cst Sequential Consistency
memory_order_acq_rel Acquire/Release
memory_order_release Release
memory_order_acquire Acquire
memory_order_consume Consume
memory_order_relaxed Relaxed
You can feed these into atomic functions with the _explicit suffix.
The non-_explcit versions of the functions are the same as if you’d called the _explicit counterpart with
memory_order_seq_cst.
1
Maybe it depends on the run-time environment and can’t be known at compile-time.
Chapter 18. <stdatomic.h> Atomic-Related Functions 181
18.5 ATOMIC_VAR_INIT()
Create an initializer for an atomic variable
Synopsis
#include <stdatomic.h>
Description
This macro expands to an initializer, so you can use it when a variable is defined.
The type of the value should be the base type of the atomic variable.
The initialization itself is not an atomic operation, ironically.
CPPReference says this is deprecated2 and likely to be removed. Standards document p1138r03 elaborates
that the macro is limited in that it can’t properly initialize atomic structs, and its original raison d’être
turned out to not be useful.
Just initialize the variable straight-up, instead.
Return Value
Expands to an initializer suitable for this atomic variable.
Example
1 #include <stdio.h>
2 #include <stdatomic.h>
3
4 int main(void)
5 {
6 atomic_int x = ATOMIC_VAR_INIT(3490); // Deprecated
7 printf("%d\n", x);
8 }
See Also
atomic_init()
18.6 atomic_init()
Initialize an atomic variable
2
https://en.cppreference.com/w/cpp/atomic/ATOMIC_VAR_INIT
3
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1138r0.pdf
Chapter 18. <stdatomic.h> Atomic-Related Functions 182
Synopsis
#include <stdatomic.h>
Description
You can use this to initialize an atomic variable.
The type of the value should be the base type of the atomic variable.
The initialization itself is not an atomic operation, ironically.
As far as I can tell, there’s no difference between this and assigning directly to the atomic variable. The spec
says it’s there to allow the compiler to inject any additional initialization that needs doing, but everything
seems fine without it. If anyone has more info, send it my way.
Return Value
Returns nothing!
Example
1 #include <stdio.h>
2 #include <stdatomic.h>
3
4 int main(void)
5 {
6 atomic_int x;
7
8 atomic_init(&x, 3490);
9
10 printf("%d\n", x);
11 }
See Also
ATOMIC_VAR_INIT(), atomic_store(), atomic_store_explicit()
18.7 kill_dependency()
End a dependency chain
Synopsis
#include <stdatomic.h>
Description
This is potentially useful for optimizing if you’re using memory_order_consume anywhere.
And if you know what you’re doing. If unsure, learn more before trying to use this.
Return Value
Returns the value passed in.
Example
In this example, i carries a dependency into x. And would do into y, except for the call to
kill_dependency().
1 #include <stdio.h>
2 #include <stdatomic.h>
3
4 int main(void)
5 {
6 atomic_int a;
7 int i = 10, x, y;
8
11 i = atomic_load_explicit(&a, memory_order_consume);
12 x = i;
13 y = kill_dependency(i);
14
18.8 atomic_thread_fence()
Set up a fence
Synopsis
#include <stdatomic.h>
Description
This sets up a memory fence with the specified order.
order Description
memory_order_seq_cst Sequentially consistency acquire/release fence
memory_order_acq_rel Acquire/release dence
memory_order_release Release fence
memory_order_acquire Acquire fence
memory_order_consume Acquire fence (again)
Chapter 18. <stdatomic.h> Atomic-Related Functions 184
order Description
memory_order_relaxed No fence at all—no point in calling with this
You might try to avoid using these and just stick with the different modes with atomic_store_explicit()
and atomic_load_explicit(). Or not.
Return Value
Returns nothing!
Example
1 #include <stdio.h>
2 #include <threads.h>
3 #include <stdatomic.h>
4
5 atomic_int shared_1 = 1;
6 atomic_int shared_2 = 2;
7
14 atomic_thread_fence(memory_order_release);
15
18 return 0;
19 }
20
29 atomic_thread_fence(memory_order_acquire);
30
31 if (shared_2 == 20) {
32 printf("Shared_1 better be 10 and it's %d\n", shared_1);
33 } else {
34 printf("Anything's possible: %d %d\n", shared_1, shared_2);
35 }
36
37 return 0;
38 }
39
40 int main(void)
Chapter 18. <stdatomic.h> Atomic-Related Functions 185
41 {
42 thrd_t t1, t2;
43
47 thrd_join(t1, NULL);
48 thrd_join(t2, NULL);
49 }
See Also
atomic_store_explicit(), atomic_load_explicit(), atomic_signal_fence()
18.9 atomic_signal_fence()
Fence for intra-thread signal handlers
Synopsis
#include <stdatomic.h>
Description
This works like atomic_thread_fence() except its purpose is within in a single thread; notably for use in
a signal handler in that thread.
Since signals can happen at any time, we might need a way to be certain that any writes by the thread that
happened before the signal handler be visible within that signal handler.
Return Value
Returns nothing!
Example
Partial demo. (Note that it’s technically undefined behavior to call printf() in a signal handler.)
1 #include <stdio.h>
2 #include <signal.h>
3 #include <stdatomic.h>
4
5 int global;
6
16 atomic_signal_fence(memory_order_acquire);
17
18 printf("%d\n", global);
19 }
20
21 int main(void)
22 {
23 signal(SIGINT, handler);
24
25 global = 10;
26
27 atomic_signal_fence(memory_order_release);
28
See Also
atomic_thread_fence(), signal()
18.10 atomic_is_lock_free()
Determine if an atomic type is lock free
Synopsis
#include <stdatomic.h>
Description
Determines if the variable obj of type A is lock-free. Can be used with any type.
Unlike the lock-free macros which can be used at compile-time, this is strictly a run-time function. So in
places where the macros say “maybe”, this function will definitely tell you one way or another if the atomic
variable is lock-free.
This is useful when you’re defining your own atomic variables and want to know their lock-free status.
Return Value
True if the variable is lock-free, false otherwise.
Chapter 18. <stdatomic.h> Atomic-Related Functions 187
Example
Test if a couple structs and an atomic double are lock-free. On my system, the larger struct is too big
to be lock-free, but the other two are OK.
1 #include <stdio.h>
2 #include <stdatomic.h>
3
4 int main(void)
5 {
6 struct foo {
7 int x, y;
8 };
9
10 struct bar {
11 int x, y, z;
12 };
13
14 _Atomic(double) a;
15 struct foo b;
16 struct bar c;
17
See Also
Lock-free Macros
18.11 atomic_store()
Store a value in an atomic variable
Synopsis
#include <stdatomic.h>
Description
Store a value in an atomic variable, possible synchronized.
Chapter 18. <stdatomic.h> Atomic-Related Functions 188
But the last function, atomic_store_explicit(), lets you specify the memory order.
Since this is a “release-y” operation, none of the “acquire-y” memory orders are legal. order can be only be
memory_order_seq_cst, memory_order_release, or memory_order_relaxed.
Return Value
Returns nothing!
Example
1 #include <stdio.h>
2 #include <stdatomic.h>
3
4 int main(void)
5 {
6 atomic_int x = 0;
7 atomic_int y = 0;
8
9 atomic_store(&x, 10);
10
See Also
atomic_init(), atomic_load(), atomic_load_explicit(), atomic_exchange(),
atomic_exchange_explicit(), atomic_compare_exchange_strong(),
atomic_compare_exchange_strong_explicit(), atomic_compare_exchange_weak(),
atomic_compare_exchange_weak_explicit(), atomic_fetch_*()
18.12 atomic_load()
Return a value from an atomic variable
Synopsis
#include <stdatomic.h>
Description
For a pointer to an object of type A, atomically returns its value C. This is a generic function that can be
used with any type.
The function atomic_load_explicit() lets you specify the memory order.
Since this is an “acquire-y” operation, none of the “release-y” memory orders are legal. order can
be only be memory_order_seq_cst, memory_order_acquire, memory_order_consume, or mem-
ory_order_relaxed.
Return Value
Returns the value stored in object.
Example
1 #include <stdio.h>
2 #include <stdatomic.h>
3
4 int main(void)
5 {
6 atomic_int x = 10;
7
8 int v = atomic_load(&x);
9
10 printf("%d\n", v); // 10
11 }
See Also
atomic_store(), atomic_store_explicit()
18.13 atomic_exchange()
Replace a value in an atomic object
Synopsis
#include <stdatomic.h>
Description
Sets the value in object to desired.
object is type A, some atomic type.
This is very similar to atomic_store(), except the previous value is atomically returned.
Return Value
Returns the previous value of object.
Example
1 #include <stdio.h>
2 #include <stdatomic.h>
3
4 int main(void)
5 {
6 atomic_int x = 10;
7
Output:
x is 20
x was 10
See Also
atomic_init(), atomic_load(), atomic_load_explicit(), atomic_store(),
atomic_store_explicit() atomic_compare_exchange_strong(),
atomic_compare_exchange_strong_explicit(), atomic_compare_exchange_weak(),
atomic_compare_exchange_weak_explicit()
18.14 atomic_compare_exchange_*()
Atomic compare and exchange
Synopsis
#include <stdatomic.h>
memory_order success,
memory_order failure);
Description
The venerable basis for some many things lock-free: compare and exchange.
In the above prototypes, A is the type of the atomic object, and C is the equivalent base type.
Ignoring the _explicit versions for a moment, what these do is:
• If the value pointed to by object is equal to the value pointed to by expected, then the value pointed
to by object is set to desired. And the function returns true indicating the exchange did take place.
• Else the value pointed to by expected (yes, expected) is set to desired and the function returns
false indicating the exchange did not take place.
*expected = desired
return false
}
The _weak variants might spontaneously fail, so even if *object == *desired, it might not change the
value and will return false. So you’ll want that in a loop if you use it5 .
The _explicit variants have two memory orders: success if *object is set to desired, and failure if
it is not.
These are test-and-set functions, so you can use memory_order_acq_rel with the _explicit variants.
Return Value
Returns true if *object was *expected. Otherwise, false.
Example
A contrived example where multiple threads add 2 to a shared value in a lock-free way.
4
This effectively does the same thing, but it’s clearly not atomic.
5
The spec says, “This spurious failure enables implementation of compare-and-exchange on a broader class of machines, e.g. load-
locked store-conditional machines.” And adds, “When a compare-and-exchange is in a loop, the weak version will yield better perfor-
mance on some platforms. When a weak compare-and-exchange would require a loop and a strong one would not, the strong one is
preferable.”
Chapter 18. <stdatomic.h> Atomic-Related Functions 192
(It would be better to use += 2 to get this done in real life unless you were using some _explicit wizardry.)
1 #include <stdio.h>
2 #include <threads.h>
3 #include <stdatomic.h>
4
7 atomic_int value;
8
18 do {
19 next = cur + 2;
20 } while (!atomic_compare_exchange_strong(&value, &cur, next));
21 }
22
23 return 0;
24 }
25
26 int main(void)
27 {
28 thrd_t t1, t2;
29
33 thrd_join(t1, NULL);
34 thrd_join(t2, NULL);
35
See Also
atomic_load(), atomic_load_explicit(), atomic_store(), atomic_store_explicit(),
atomic_exchange(), atomic_exchange_explicit(), atomic_fetch_*()
18.15 atomic_fetch_*()
Atomically modify atomic variables
Chapter 18. <stdatomic.h> Atomic-Related Functions 193
Synopsis
#include <stdatomic.h>
Description
These are actually a group of 10 functions. You substitute one of the following for KEY to perform that
operation:
• add
• sub
• or
• xor
• and
So these functions can add or subtract values to or from an atomic variable, or can perform bitwise-OR, XOR,
or AND on them.
Use it with integer or pointer types. Though the spec is a little vague on the matter, other types make C
unhappy. It goes out of its way to avoid undefined behavior with signed integers, as well:
C18 §7.17.7.5 ¶3:
For signed integer types, arithmetic is defined to use two’s complement representation with silent
wrap-around on overflow; there are no undefined results.
In the synopsis, above, A is an atomic type, and M is the corresponding non-atomic type for A (or ptrdiff_t
for atomic pointers), and C is the corresponding non-atomic type for A.
For example, here are some operations on an atomic_int.
atomic_fetch_add(&x, 20);
atomic_fetch_sub(&x, 37);
atomic_fetch_xor(&x, 3490);
They are the same as +=, -=, |=, ^= and &=, except the return value is the previous value of the atomic object.
(With the assignment operators, the value of the expression is that after its evaluation.)
atomic_int x = 10;
int prev = atomic_fetch_add(&x, 20);
printf("%d %d\n", prev, x); // 10 30
versus:
atomic_int x = 10;
int prev = (x += 20);
printf("%d %d\n", prev, x); // 30 30
And, of course, the _explicit version allows you to specify a memory order and all the assignment operators
are memory_order_seq_cst.
Return Value
Returns the previous value of the atomic object before the modification.
Chapter 18. <stdatomic.h> Atomic-Related Functions 194
Example
1 #include <stdio.h>
2 #include <stdatomic.h>
3
4 int main(void)
5 {
6 atomic_int x = 0;
7 int prev;
8
9 atomic_fetch_add(&x, 3490);
10 atomic_fetch_sub(&x, 12);
11 atomic_fetch_xor(&x, 444);
12 atomic_fetch_or(&x, 12);
13 prev = atomic_fetch_and(&x, 42);
14
See Also
atomic_exchange(), atomic_exchange_explicit(), atomic_compare_exchange_strong(),
atomic_compare_exchange_strong_explicit(), atomic_compare_exchange_weak(),
atomic_compare_exchange_weak_explicit()
18.16 atomic_flag_test_and_set()
Test and set an atomic flag
Synopsis
#include <stdatomic.h>
Description
One of the venerable old functions of lock-free programming, this function sets the given atomic flag in
object, and returns the previous value of the flag.
Return Value
Returns true if the flag was set previously, and false if it wasn’t.
Chapter 18. <stdatomic.h> Atomic-Related Functions 195
Example
Using test-and-set to implement a spin lock6 :
1 #include <stdio.h>
2 #include <threads.h>
3 #include <stdatomic.h>
4
10 atomic_flag f = ATOMIC_FLAG_INIT;
11
18 while (atomic_flag_test_and_set(&f));
19
30 return 0;
31 }
32
33 int main(void)
34 {
35 thrd_t t1, t2;
36 int tid[] = {0, 1};
37
41 thrd_join(t1, NULL);
42 thrd_join(t2, NULL);
43 }
6
Don’t use this unless you know what you’re doing—use the thread mutex functionality instead. It’ll let your blocked thread sleep
and stop chewing up CPU.
Chapter 18. <stdatomic.h> Atomic-Related Functions 196
See Also
atomic_flag_clear()
18.17 atomic_flag_clear()
Clear an atomic flag
Synopsis
#include <stdatomic.h>
Description
Clears an atomic flag.
As usual, the _explicit allows you to specify an alternate memory order.
Return Value
Returns nothing!
Example
Using test-and-set to implement a spin lock7 :
1 #include <stdio.h>
2 #include <threads.h>
3 #include <stdatomic.h>
4
10 atomic_flag f = ATOMIC_FLAG_INIT;
11
7
Don’t use this unless you know what you’re doing—use the thread mutex functionality instead. It’ll let your blocked thread sleep
and stop chewing up CPU.
Chapter 18. <stdatomic.h> Atomic-Related Functions 197
13 {
14 int tid = *(int*)arg;
15
18 while (atomic_flag_test_and_set(&f));
19
30 return 0;
31 }
32
33 int main(void)
34 {
35 thrd_t t1, t2;
36 int tid[] = {0, 1};
37
41 thrd_join(t1, NULL);
42 thrd_join(t2, NULL);
43 }
See Also
atomic_flag_test_and_set()
Chapter 19
This is a small header file that defines a number of convenient Boolean macros. If you really need that kind
of thing.
Macro Description
bool Type for Boolean, expands to _Bool
true True value, expands to 1
false False value, expands to 0
There’s one more macro that I’m not putting in the table because it’s such a long name it’ll blow up the table
alignment:
__bool_true_false_are_defined
which expands to 1.
19.1 Example
Here’s a lame example that shows off these macros.
1 #include <stdio.h>
2 #include <stdbool.h>
3
4 int main(void)
5 {
6 bool x;
7
8 x = (3 > 2);
9
10 if (x == true)
11 printf("The universe still makes sense.\n");
12
13 x = false;
14
Output:
198
Chapter 19. <stdbool.h> Boolean Types 199
19.2 _Bool?
What’s the deal with _Bool? Why didn’t they just make it bool?
Well, there was a lot of C code out there where people had defined their own bool type and adding an official
bool would have broken those typedefs.
But C has already reserved all identifiers that start with an underscore followed by a capital letter, so it was
clear to make up a new _Bool type and go with that.
And, if you know your code can handle it, you can include this header to get all this juicy syntax.
One more note on conversions: unlike converting to int, the only thing that converts to false in a _Bool
is a scalar zero value. Anything at all that’s not zero, like -3490, 0.12, or NaN, converts to true.
Chapter 20
Name Description
ptrdiff_t Signed integer difference between two pointers
size_t Unsigned integer type returned by sizeof
max_align_t Declare a type with the biggest possible alignment
wchar_t Wide character type
NULL NULL pointer, as defined a number of places
offsetof Get the byte offsets of struct or union fields
20.1 ptrdiff_t
This holds the different between two pointers. You could store this in another type, but the result of a pointer
subtraction is an implementation-defined type; you can be maximally portable by using ptrdiff_t.
1 #include <stdio.h>
2 #include <stddef.h>
3
4 int main(void)
5 {
6 int cats[100];
7
11 ptrdiff_t d = g - f; // difference is 40
And you can print it by prefixing the integer format specifier with t:
13 printf("%td\n", d); // Print decimal: 40
14 printf("%tX\n", d); // Print hex: 28
15 }
200
Chapter 20. <stddef.h> A Few Standard Definitions 201
20.2 size_t
This is the type returned by sizeof and used in a few other places. It’s an unsigned integer.
You can print it using the z prefix in printf():
1 #include <stdio.h>
2 #include <uchar.h>
3 #include <string.h>
4 #include <stddef.h>
5
6 int main(void)
7 {
8 size_t x;
9
10 x = sizeof(int);
11
12 printf("%zu\n", x);
Some functions return negative numbers cast to size_t as error values (such as mbrtoc16()). If you want
to print these as negative values, you can do it with %zd:
14 char16_t a;
15 mbstate_t mbs;
16 memset(&mbs, 0, sizeof mbs);
17
20 printf("%zd\n", x);
21 }
20.3 max_align_t
As far as I can tell, this exists to allow the runtime computation of the maximum fundamental alignment1 on
the current platform. Someone please mail me if there’s another use.
Maybe you need this if you’re writing your own memory allocator or somesuch.
1 #include <stddef.h>
2 #include <stdio.h> // For printf()
3 #include <stdalign.h> // For alignof
4
5 int main(void)
6 {
7 int max = alignof(max_align_t);
8
20.4 wchar_t
This is analogous to char, except it’s for wide characters.
It’s an integer type that has enough range to hold unique values for all characters in all supported locales.
The value 0 is the wide NUL character.
Finally, the values of character constants from the basic character set will be the same as their corresponding
wchar_t values… unless __STDC_MB_MIGHT_NEQ_WC__ is defined.
20.5 offsetof
If you have a struct or union, you can use this to get the byte offset of fields within that type.
Usage is:
offsetof(type, fieldname);
4 struct foo {
5 int a;
6 char b;
7 char c;
8 float d;
9 };
10
11 int main(void)
12 {
13 printf("a: %zu\n", offsetof(struct foo, a));
14 printf("b: %zu\n", offsetof(struct foo, b));
15 printf("c: %zu\n", offsetof(struct foo, c));
16 printf("d: %zu\n", offsetof(struct foo, d));
17 }
And you can’t use offsetof on a bitfield, so don’t get your hopes up.
Chapter 21
This header gives us access to (potentially) types of a fixed number of bits, or, at the very least, types that
are at least that many bits.
It also gives us handy macros to use.
int_fast8_t uint_fast8_t
int_fast16_t uint_fast16_t
int_fast32_t uint_fast32_t
int_fast64_t uint_fast64_t
Everything else is optional, but you’ll probably also have the following, which are required when a system
has integers of these sizes with no padding and two’s-complement representation… which is the case for
Macs and PCs and a lot of other systems. In short, you very likely have these:
int8_t uint8_t
int16_t uint16_t
int32_t uint32_t
int64_t uint64_t
Other numbers of bits can also be supported by an implementation if it wants to go all crazy with it.
Examples:
203
Chapter 21. <stdint.h> More Integer Types 204
#include <stdint.h>
int main(void)
{
int16_t x = 32;
int_fast32_t y = 3490;
// ...
You can convert a void* to one of these types, and back again. And the void*s will compare equal.
The use case is any place you need an integer that represents a pointer for some reason.
Also, there are a couple types that are just there to be the biggest possible integers your system supports:
intmax_t
uintmax_t
Fun fact: you can print these types with the "%jd" and "%ju" printf() format specifiers.
There are also a bunch of macros in <inttypes.h>(#inttypes) that you can use to print any of the types
mentioned, above.
21.3 Macros
The following macros define the minimum and maximum values for these types:
INT8_MAX INT8_MIN UINT8_MAX
INT16_MAX INT16_MIN UINT16_MAX
INT32_MAX INT32_MIN UINT32_MAX
INT64_MAX INT64_MIN UINT64_MAX
For the exact-bit-size signed types, the minimum is exactly −(2𝑁−1 ) and the maximum is exactly 2𝑁−1 − 1.
And for the exact-bit-size unsigned types, the max is exactly 2𝑁 − 1.
Chapter 21. <stdint.h> More Integer Types 205
For the signed “least” and “fast” variants, the magnitude and sign of the minimum is at least −(2𝑁−1 − 1)
and the maximum is at least 2𝑁−1 − 1. And for unsigned it’s at least 2𝑁 − 1.
INTMAX_MAX is at least 263 −1, INTMAX_MIN is at least −(263 −1) in sign and magnitude. And UINTMAX_MAX
is at least 264 − 1.
Finally, INTPTR_MAX is at least 215 − 1, INTPTR_MIN is at least −(215 − 1) in sign and magnitude. And
UINTPTR_MAX is at least 216 − 1.
Macro Description
PTRDIFF_MIN Minimum ptrdiff_t value
PTRDIFF_MAX Maximum ptrdiff_t value
SIG_ATOMIC_MIN Minimum sig_atomic_t value
SIG_ATOMIC_MAX Maximum sig_atomic_t value
SIZE_MAX Maximum size_t value
WCHAR_MIN Minimum wchar_t value
WCHAR_MAX Maximum wchar_t value
WINT_MIN Minimum wint_t value
WINT_MAX Maximum wint_t value
The spec says that PTRDIFF_MIN will be at least -65535 in magnitude. And PTRDIFF_MAX and SIZE_MAX
will be at least 65535.
SIG_ATOMIC_MIN and MAX will be either -127 and 127 (if it’s signed) or 0 and 255 (if it’s unsigned).
You can use the macros INTN _C() and UINTN () where N is 8, 16, 32 or 64.
uint_least16_t x = INT16_C(3490);
uint_least64_t y = INT64_C(1122334455);
A variant on these is INTMAX_C() and UINTMAX_C(). They will make a constant suitable for storing in an
intmax_t or uintmax_t.
intmax_t x = INTMAX_C(3490);
uintmax_t x = UINTMAX_C(1122334455);
Chapter 22
Function Description
clearerr() Clear the feof and ferror status flags
fclose() Close an open file
feof() Return the file end-of-file status
ferror() Return the file error status
fflush() Flush all buffered output to a file
fgetc() Read a character in a file
fgetpos() Get the file I/O position
fgets() Read a line from a file
fopen() Open a file
fprintf() Print formatted output to a file
fputc() Print a character to a file
fputs() Print a string to a file
fread() Read binary data from a file
freopen() Change file associated with a stream
fscanf() Read formatted input from a file
fseek() Set the file I/O position
fsetpos() Set the file I/O position
ftell() Get the file I/O position
fwrite() Write binary data to a file
getc() Get a character from stdin
getchar() Get a character from stdin
gets() Get a string from stdin (removed in C11)
perror() Print a human-formatted error message
printf() Print formatted output to stdout
putc() Print a character to stdout
putchar() Print a character to stdout
puts() Print a string to stdout
remove() Delete a file from disk
rename() Rename or move a file on disk
rewind() Set the I/O position to the beginning of a file
scanf() Read formatted input from stdin
setbuf() Configure buffering for I/O operations
setvbuf() Configure buffering for I/O operations
snprintf() Print length-limited formatted output to a string
sprintf() Print formatted output to a string
206
Chapter 22. <stdio.h> Standard I/O Library 207
Function Description
sscanf() Read formatted input from a string
tmpfile() Create a temporary file
tmpnam() Generate a unique name for a temporary file
ungetc() Push a character back on the input stream
vfprintf() Variadic print formatted output to a file
vfscanf() Variadic read formatted input from a file
vprintf() Variadic print formatted output to stdout
vscanf() Variadic read formatted input from stdin
vsnprintf() Variadic length-limited print formatted output to a
string
vsprintf() Variadic print formatted output to a string
vsscanf() Variadic read formatted input to a string
The most basic of all libraries in the whole of the standard C library is the standard I/O library. It’s used for
reading from and writing to files. I can see you’re very excited about this.
So I’ll continue. It’s also used for reading and writing to the console, as we’ve already often seen with the
printf() function.
(A little secret here—many many things in various operating systems are secretly files deep down, and the
console is no exception. “Everything in Unix is a file!” :-))
You’ll probably want some prototypes of the functions you can use, right? To get your grubby little mittens
on those, you’ll want to include stdio.h.
Anyway, so we can do all kinds of cool stuff in terms of file I/O. LIE DETECTED. Ok, ok. We can do all
kinds of stuff in terms of file I/O. Basically, the strategy is this:
1. Use fopen() to get a pointer to a file structure of type FILE*. This pointer is what you’ll be passing
to many of the other file I/O calls.
2. Use some of the other file calls, like fscanf(), fgets(), fprintf(), or etc. using the FILE* returned
from fopen().
3. When done, call fclose() with the FILE*. This let’s the operating system know that you’re truly
done with the file, no take-backs.
What’s in the FILE*? Well, as you might guess, it points to a struct that contains all kinds of information
about the current read and write position in the file, how the file was opened, and other stuff like that. But,
honestly, who cares. No one, that’s who. The FILE structure is opaque to you as a programmer; that is, you
don’t need to know what’s in it, and you don’t even want to know what’s in it. You just pass it to the other
standard I/O functions and they know what to do.
This is actually pretty important: try to not muck around in the FILE structure. It’s not even the same from
system to system, and you’ll end up writing some really non-portable code.
One more thing to mention about the standard I/O library: a lot of the functions that operate on files use an
“f” prefix on the function name. The same function that is operating on the console will leave the “f” off.
For instance, if you want to print to the console, you use printf(), but if you want to print to a file, use
fprintf(), see?
Wait a moment! If writing to the console is, deep down, just like writing to a file, since everything in Unix is
a file, why are there two functions? Answer: it’s more convenient. But, more importantly, is there a FILE*
associated with the console that you can use? Answer: YES!
There are, in fact, three (count ’em!) special FILE*s you have at your disposal merely for just including
stdio.h. There is one for input, and two for output.
Chapter 22. <stdio.h> Standard I/O Library 208
That hardly seems fair—why does output get two files, and input only get one?
That’s jumping the gun a bit—let’s just look at them:
Stream Description
stdin Input from the console.
stdout Output to the console.
stderr Output to the console on the error file stream.
So standard input (stdin) is by default just what you type at the keyboard. You can use that in fscanf() if
you want, just like this:
/* this line: */
scanf("%d", &x);
So what is this stderr thing? What happens when you output to that? Well, generally it goes to the console
just like stdout, but people use it for error messages, specifically. Why? On many systems you can redirect
the output from the program into a file from the command line…and sometimes you’re interested in getting
just the error output. So if the program is good and writes all its errors to stderr, a user can redirect just
stderr into a file, and just see that. It’s just a nice thing you, as a programmer, can do.
Finally, a lot of these functions return int where you might expect char. This is because the function can
return a character or end-of-file (EOF), and EOF is potentially an integer. If you don’t get EOF as a return
value, you can safely store the result in a char.
22.1 remove()
Delete a file
Synopsis
#include <stdio.h>
Description
Removes the specified file from the filesystem. It just deletes it. Nothing magical. Simply call this function
and sacrifice a small chicken and the requested file will be deleted.
Return Value
Returns zero on success, and -1 on error, setting errno.
Chapter 22. <stdio.h> Standard I/O Library 209
Example
1 #include <stdio.h>
2
3 int main(void)
4 {
5 char *filename = "evidence.txt";
6
7 remove(filename);
8 }
See Also
rename()
22.2 rename()
Renames a file and optionally moves it to a new location
Synopsis
#include <stdio.h>
Description
Renames the file old to name new. Use this function if you’re tired of the old name of the file, and you are
ready for a change. Sometimes simply renaming your files makes them feel new again, and could save you
money over just getting all new files!
One other cool thing you can do with this function is actually move a file from one directory to another by
specifying a different path for the new name.
Return Value
Returns zero on success, and -1 on error, setting errno.
Example
1 #include <stdio.h>
2
3 int main(void)
4 {
5 // Rename a file
6 rename("foo", "bar");
7
See Also
remove()
22.3 tmpfile()
Create a temporary file
Synopsis
#include <stdio.h>
FILE *tmpfile(void);
Description
This is a nifty little function that will create and open a temporary file for you, and will return a FILE* to it
that you can use. The file is opened with mode “r+b”, so it’s suitable for reading, writing, and binary data.
By using a little magic, the temp file is automatically deleted when it is close()’d or when your program
exits. (Specifically, in Unix terms, tmpfile() unlinks1 the file right after it opens it. This means that it’s
primed to be deleted from disk, but still exists because your process still has it open. As soon as your process
exits, all open files are closed, and the temp file vanishes into the ether.)
Return Value
This function returns an open FILE* on success, or NULL on failure.
Example
1 #include <stdio.h>
2
3 int main(void)
4 {
5 FILE *temp;
6 char s[128];
7
8 temp = tmpfile();
9
1
https://man.archlinux.org/man/unlinkat.2.en#DESCRIPTION
Chapter 22. <stdio.h> Standard I/O Library 211
See Also
fopen(), fclose(), tmpnam()
22.4 tmpnam()
Generate a unique name for a temporary file
Synopsis
#include <stdio.h>
Description
This function takes a good hard look at the existing files on your system, and comes up with a unique name
for a new file that is suitable for temporary file usage.
Let’s say you have a program that needs to store off some data for a short time so you create a temporary file
for the data, to be deleted when the program is done running. Now imagine that you called this file foo.txt.
This is all well and good, except what if a user already has a file called foo.txt in the directory that you
ran your program from? You’d overwrite their file, and they’d be unhappy and stalk you forever. And you
wouldn’t want that, now would you?
Ok, so you get wise, and you decide to put the file in /tmp so that it won’t overwrite any important content.
But wait! What if some other user is running your program at the same time and they both want to use that
filename? Or what if some other program has already created that file?
See, all of these scary problems can be completely avoided if you just use tmpnam() to get a safe-ready-to-use
filename.
So how do you use it? There are two amazing ways. One, you can declare an array (or malloc() it—
whatever) that is big enough to hold the temporary file name. How big is that? Fortunately there has been a
macro defined for you, L_tmpnam, which is how big the array must be.
And the second way: just pass NULL for the filename. tmpnam() will store the temporary name in a static
array and return a pointer to that. Subsequent calls with a NULL argument will overwrite the static array, so
be sure you’re done using it before you call tmpnam() again.
Again, this function just makes a file name for you. It’s up to you to later fopen() the file and use it.
One more note: some compilers warn against using tmpnam() since some systems have better functions (like
the Unix function mkstemp().) You might want to check your local documentation to see if there’s a better
option. Linux documentation goes so far as to say, “Never use this function. Use mkstemp() instead.”
I, however, am going to be a jerk and not talk about mkstemp()2 because it’s not in the standard I’m writing
about. Nyaah.
The macro TMP_MAX holds the number of unique filenames that can be generated by tmpnam(). Ironically,
it is the minimum number of such filenames.
2
https://man.archlinux.org/man/mkstemp.3.en
Chapter 22. <stdio.h> Standard I/O Library 212
Return Value
Returns a pointer to the temporary file name. This is either a pointer to the string you passed in, or a pointer
to internal static storage if you passed in NULL. On error (like it can’t find any temporary name that is unique),
tmpnam() returns NULL.
Example
1 #include <stdio.h>
2
3 int main(void)
4 {
5 char filename[L_tmpnam];
6 char *another_filename;
7
8 if (tmpnam(filename) != NULL)
9 printf("We got a temp file name: \"%s\"\n", filename);
10 else
11 printf("Something went wrong, and we got nothing!\n");
12
13 another_filename = tmpnam(NULL);
14
See Also
fopen(), tmpfile()
22.5 fclose()
The opposite of fopen()—closes a file when you’re done with it so that it frees system resources
Synopsis
#include <stdio.h>
Description
When you open a file, the system sets aside some resources to maintain information about that open file.
Usually it can only open so many files at once. In any case, the Right Thing to do is to close your files when
you’re done using them so that the system resources are freed.
Chapter 22. <stdio.h> Standard I/O Library 213
Also, you might not find that all the information that you’ve written to the file has actually been written to
disk until the file is closed. (You can force this with a call to fflush().)
When your program exits normally, it closes all open files for you. Lots of times, though, you’ll have a
long-running program, and it’d be better to close the files before then. In any case, not closing a file you’ve
opened makes you look bad. So, remember to fclose() your file when you’re done with it!
Return Value
On success, 0 is returned. Typically no one checks for this. On error EOF is returned. Typically no one checks
for this, either.
Example
1 #include <stdio.h>
2
3 int main(void)
4 {
5 FILE *fp;
6
7 fp = fopen("spoon.txt", "r");
8
9 if (fp == NULL) {
10 printf("Error opening file\n");
11 } else {
12 printf("Opened file just fine!\n");
13 fclose(fp); // All done!
14 }
15 }
See Also
fopen()
22.6 fflush()
Process all buffered I/O for a stream right now
Synopsis
#include <stdio.h>
Description
When you do standard I/O, as mentioned in the section on the setvbuf() function, it is usually stored in a
buffer until a line has been entered or the buffer is full or the file is closed. Sometimes, though, you really
want the output to happen right this second, and not wait around in the buffer. You can force this to happen
by calling fflush().
Chapter 22. <stdio.h> Standard I/O Library 214
The advantage to buffering is that the OS doesn’t need to hit the disk every time you call fprintf(). The
disadvantage is that if you look at the file on the disk after the fprintf() call, it might not have actually
been written to yet. (“I called fputs(), but the file is still zero bytes long! Why?!”) In virtually all circum-
stances, the advantages of buffering outweigh the disadvantages; for those other circumstances, however,
use fflush().
Note that fflush() is only designed to work on output streams according to the spec. What will happen if
you try it on an input stream? Use your spooky voice: who knooooows!
Return Value
On success, fflush() returns zero. If there’s an error, it returns EOF and sets the error condition for the
stream (see ferror().)
Example
In this example, we’re going to use the carriage return, which is '\r'. This is like newline ('\n'), except
that it doesn’t move to the next line. It just returns to the front of the current line.
What we’re going to do is a little text-based status bar like so many command line programs implement. It’ll
do a countdown from 10 to 0 printing over itself on the same line.
What is the catch and what does this have to do with fflush()? The catch is that the terminal is most likely
“line buffered” (see the section on setvbuf() for more info), meaning that it won’t actually display anything
until it prints a newline. But we’re not printing newlines; we’re just printing carriage returns, so we need a
way to force the output to occur even though we’re on the same line. Yes, it’s fflush()!
1 #include <stdio.h>
2 #include <threads.h>
3
4 void sleep_seconds(int s)
5 {
6 thrd_sleep(&(struct timespec){.tv_sec=s}, NULL);
7 }
8
9 int main(void)
10 {
11 int count;
12
23 sleep_seconds(1);
24 }
25 }
See Also
setbuf(), setvbuf()
Chapter 22. <stdio.h> Standard I/O Library 215
22.7 fopen()
Opens a file for reading or writing
Synopsis
#include <stdio.h>
Description
The fopen() opens a file for reading or writing.
Parameter path can be a relative or fully-qualified path and file name to the file in question.
Parameter mode tells fopen() how to open the file (reading, writing, or both), and whether or not it’s a binary
file. Possible modes are:
Mode Description
r Open the file for reading (read-only).
w Open the file for writing (write-only). The file is
created if it doesn’t exist.
r+ Open the file for reading and writing. The file has
to already exist.
w+ Open the file for writing and reading. The file is
created if it doesn’t already exist.
a Open the file for append. This is just like opening a
file for writing, but it positions the file pointer at the
end of the file, so the next write appends to the end.
The file is created if it doesn’t exist.
a+ Open the file for reading and appending. The file is
created if it doesn’t exist.
Any of the modes can have the letter “b” appended to the end, as is “wb” (“write binary”), to signify that the
file in question is a binary file. (“Binary” in this case generally means that the file contains non-alphanumeric
characters that look like garbage to human eyes.) Many systems (like Unix) don’t differentiate between binary
and non-binary files, so the “b” is extraneous. But if your data is binary, it doesn’t hurt to throw the “b” in
there, and it might help someone who is trying to port your code to another system.
The macro FOPEN_MAX tells you how many streams (at least) you can have open at once.
The macro FILENAME_MAX tells you what the longest valid filename can be. Don’t go crazy, now.
Return Value
fopen() returns a FILE* that can be used in subsequent file-related calls.
If something goes wrong (e.g. you tried to open a file for read that didn’t exist), fopen() will return NULL.
Chapter 22. <stdio.h> Standard I/O Library 216
Example
1 #include <stdio.h>
2
3 int main(void)
4 {
5 FILE *fp;
6
7 fp = fopen("spoon.txt", "r");
8
9 if (fp == NULL) {
10 printf("Error opening file\n");
11 } else {
12 printf("Opened file just fine!\n");
13 fclose(fp); // All done!
14 }
15 }
See Also
fclose(), freopen()
22.8 freopen()
Reopen an existing FILE*, associating it with a new path
Synopsis
#include <stdio.h>
Description
Let’s say you have an existing FILE* stream that’s already open, but you want it to suddenly use a different
file than the one it’s using. You can use freopen() to “re-open” the stream with a new file.
Why on Earth would you ever want to do that? Well, the most common reason would be if you had a program
that normally would read from stdin, but instead you wanted it to read from a file. Instead of changing all
your scanf()s to fscanf()s, you could simply reopen stdin on the file you wanted to read from.
Another usage that is allowed on some systems is that you can pass NULL for filename, and specify a new
mode for stream. So you could change a file from “r+” (read and write) to just “r” (read), for instance. It’s
implementation dependent which modes can be changed.
When you call freopen(), the old stream is closed. Otherwise, the function behaves just like the standard
fopen().
Return Value
freopen() returns stream if all goes well.
If something goes wrong (e.g. you tried to open a file for read that didn’t exist), freopen() will return NULL.
Chapter 22. <stdio.h> Standard I/O Library 217
Example
1 #include <stdio.h>
2
3 int main(void)
4 {
5 int i, i2;
6
See Also
fclose(), fopen()
Synopsis
#include <stdio.h>
Description
Now brace yourself because this might come as a bit of a surprise to you: when you printf() or fprintf()
or use any I/O functions like that, it does not normally work immediately. For the sake of efficiency, and to
irritate you, the I/O on a FILE* stream is buffered away safely until certain conditions are met, and only then
is the actual I/O performed. The functions setbuf() and setvbuf() allow you to change those conditions
and the buffering behavior.
So what are the different buffering behaviors? The biggest is called “full buffering”, wherein all I/O is stored
in a big buffer until it is full, and then it is dumped out to disk (or whatever the file is). The next biggest is
Chapter 22. <stdio.h> Standard I/O Library 218
called “line buffering”; with line buffering, I/O is stored up a line at a time (until a newline ('\n') character
is encountered) and then that line is processed. Finally, we have “unbuffered”, which means I/O is processed
immediately with every standard I/O call.
You might have seen and wondered why you could call putchar() time and time again and not see any
output until you called putchar('\n'); that’s right—stdout is line-buffered!
Since setbuf() is just a simplified version of setvbuf(), we’ll talk about setvbuf() first.
The stream is the FILE* you wish to modify. The standard says you must make your call to setvbuf()
before any I/O operation is performed on the stream, or else by then it might be too late.
The next argument, buf allows you to make your own buffer space (using malloc() or just a char array)
to use for buffering. If you don’t care to do this, just set buf to NULL.
Now we get to the real meat of the function: mode allows you to choose what kind of buffering you want to
use on this stream. Set it to one of the following:
Mode Description
_IOFBF stream will be fully buffered.
_IOLBF stream will be line buffered.
_IONBF stream will be unbuffered.
Finally, the size argument is the size of the array you passed in for buf…unless you passed NULL for buf,
in which case it will resize the existing buffer to the size you specify.
Now what about this lesser function setbuf()? It’s just like calling setvbuf() with some specific param-
eters, except setbuf() doesn’t return a value. The following example shows the equivalency:
// these are the same:
setbuf(stream, buf);
setvbuf(stream, buf, _IOFBF, BUFSIZ); // fully buffered
Return Value
setvbuf() returns zero on success, and nonzero on failure. setbuf() has no return value.
Example
1 #include <stdio.h>
2
3 int main(void)
4 {
5 FILE *fp;
6 char lineBuf[1024];
7
8 fp = fopen("somefile.txt", "w");
9 setvbuf(fp, lineBuf, _IOLBF, 1024); // set to line buffering
10 fprintf(fp, "You won't see this in the file yet. ");
11 fprintf(fp, "But now you will because of this newline.\n");
12 fclose(fp);
Chapter 22. <stdio.h> Standard I/O Library 219
13
14 fp = fopen("anotherfile.txt", "w");
15 setbuf(fp, NULL); // set to unbuffered
16 fprintf(fp, "You will see this in the file now.");
17 fclose(fp);
18 }
See Also
fflush()
Synopsis
#include <stdio.h>
Description
These functions print formatted output to a variety of destinations.
The only differences between these is are the leading parameters that you pass to them before the format
string.
The printf() function is legendary as being one of the most flexible outputting systems ever devised. It
can also get a bit freaky here or there, most notably in the format string. We’ll take it a step at a time here.
Chapter 22. <stdio.h> Standard I/O Library 220
The easiest way to look at the format string is that it will print everything in the string as-is, unless a character
has a percent sign (%) in front of it. That’s when the magic happens: the next argument in the printf()
argument list is printed in the way described by the percent code. These percent codes are called format
specifiers.
Here are the most common format specifiers.
Specifier Description
%d Print the next argument as a signed decimal number, like 3490. The argument printed this
way should be an int, or something that gets promoted to int.
%f Print the next argument as a signed floating point number, like 3.14159. The argument
printed this way should be a double, or something that gets promoted to a double.
%c Print the next argument as a character, like 'B'. The argument printed this way should be a
char variant.
%s Print the next argument as a string, like "Did you remember your mittens?". The
argument printed this way should be a char* or char[].
%% No arguments are converted, and a plain old run-of-the-mill percent sign is printed. This is
how you print a ‘%’ using printf().
So those are the basics. I’ll give you some more of the format specifiers in a bit, but let’s get some more
breadth before then. There’s actually a lot more that you can specify in there after the percent sign.
For one thing, you can put a field width in there—this is a number that tells printf() how many spaces to
put on one side or the other of the value you’re printing. That helps you line things up in nice columns. If
the number is negative, the result becomes left-justified instead of right-justified. Example:
printf("%10d", x); /* prints X on the right side of the 10-space field */
printf("%-10d", x); /* prints X on the left side of the 10-space field */
If you don’t know the field width in advance, you can use a little kung-foo to get it from the argument list
just before the argument itself. Do this by placing your seat and tray tables in the fully upright position. The
seatbelt is fastened by placing the—cough. I seem to have been doing way too much flying lately. Ignoring
that useless fact completely, you can specify a dynamic field width by putting a * in for the width. If you are
not willing or able to perform this task, please notify a flight attendant and we will reseat you.
int width = 12;
int value = 3490;
You can also put a “0” in front of the number if you want it to be padded with zeros:
int x = 17;
printf("%05d", x); /* "00017" */
When it comes to floating point, you can also specify how many decimal places to print by making a field
width of the form “x.y” where x is the field width (you can leave this off if you want it to be just wide
enough) and y is the number of digits past the decimal point to print:
float f = 3.1415926535;
Ok, those above are definitely the most common uses of printf(), but let’s get total coverage.
Chapter 22. <stdio.h> Standard I/O Library 221
Conversion
Specifier Description
d Print an int argument as a decimal number.
i Identical to d.
o Print an unsigned int in octal (base 8).
u Print an unsigned int in decimal.
x Print an unsigned int in hexadecimal with lowercase letters.
X Print an unsigned int in hexadecimal with uppercase letters.
f Print a double in decimal notation. Infinity is printed as infinity or inf, and NaN is
printed as nan, any of which could have a leading minus sign.
F Same as f, except it prints out INFINITY, INF, or NAN in all caps.
e Print a number in scientific notation, e.g. 1.234e56. Does infinity and NaN like f.
E Just like e, except prints the exponent E (and infinity and NaN) in uppercase.
g Print small numbers like f and large numbers like e. See note below.
G Print small numbers like F and large numbers like E. See note below.
a Print a double in hexadecimal form 0xh.hhhhpd where h is a lowercase hex digit and d
is a decimal exponent of 2. Infinity and NaN in the form of f. More below.
A Like a except everything’s uppercase.
c Convert int argument to unsigned char and print as a character.
s Print a string starting at the given char*.
p Print a void* out as a number, probably the numeric address, possibly in hex.
n Store the number of characters written so far in the given int*. Doesn’t print anything.
See below.
% Print a literal percent sign.
22.10.0.2.1 Note on %a and %A When printing floating point numbers in hex form, there is one number
before the decimal point, and the rest of are out to the precision.
double pi = 3.14159265358979;
C can choose the leading number in such a way to ensure subsequent digits align to 4-bit boundaries.
Chapter 22. <stdio.h> Standard I/O Library 222
If the precision is left out and the macro FLT_RADIX is a power of 2, enough precision is used to represent
the number exactly. If FLT_RADIX is not a power of two, enough precision is used to be able to tell any two
floating values apart.
If the precision is 0 and the # flag isn’t specified, the decimal point is omitted.
22.10.0.2.2 Note on %g and %G The gist of this is to use scientific notation when the number gets too
“extreme”, and regular decimal notation otherwise.
The exact behavior for whether these print as %f or %e depends on a number of factors:
If the number’s exponent is greater than or equal to -4 and the precision is greater than the exponent, we use
%f. In this case, the precision is converted according to 𝑝 = 𝑝 − (𝑥 + 1), where 𝑝 is the specified precision
and 𝑥 is the exponent.
Otherwise we use %e, and the precision becomes 𝑝 − 1.
Trailing zeros in the decimal portion are removed. And if there are none left, the decimal point is removed,
too. All this unless the # flag is specified.
22.10.0.2.3 Note on %n This specifier is cool and different, and rarely needed. It doesn’t actually print
anything, but stores the number of characters printed so far in the next pointer argument in the list.
int numChars;
float a = 3.14159;
int b = 3490;
The above example will print out the values of a and b, and then store the number of characters printed so
far into the variable numChars. The next call to printf() prints out that result.
3.141590 3490
The above line contains 13 characters
Length
Modifier Conversion Specifier Description
hh d, i, o, u, x, X Convert argument to char (signed or unsigned as appropriate)
before printing.
h d, i, o, u, x, X Convert argument to short int (signed or unsigned as
appropriate) before printing.
l d, i, o, u, x, X Argument is a long int (signed or unsigned as appropriate).
ll d, i, o, u, x, X Argument is a long long int (signed or unsigned as
appropriate).
j d, i, o, u, x, X Argument is a intmax_t or uintmax_t (as appropriate).
Chapter 22. <stdio.h> Standard I/O Library 223
Length
Modifier Conversion Specifier Description
z d, i, o, u, x, X Argument is a size_t.
t d, i, o, u, x, X Argument is a ptrdiff_t.
L a, A, e, E, f, F, g, G Argument is a long double.
l c Argument is in a wint_t, a wide character.
l s Argument is in a wchar_t*, a wide character string.
hh n Store result in signed char* argument.
h n Store result in short int* argument.
l n Store result in long int* argument.
ll n Store result in long long int* argument.
j n Store result in intmax_t* argument.
z n Store result in size_t* argument.
t n Store result in ptrdiff_t* argument.
22.10.0.4 Precision
In front of the length modifier, you can put a precision, which generally means how many decimal places
you want on your floating point numbers.
To do this, you put a decimal point (.) and the decimal places afterward.
For example, we could print π rounded to two decimal places like this:
double pi = 3.14159265358979;
If no number is specified in the precision after the decimal point, the precision is zero.
If an * is specified after the decimal, something amazing happens! It means the int argument to printf()
before the number to be printed holds the precision. You can use this if you don’t know the precision at
compile time.
int precision;
double pi = 3.14159265358979;
Which gives:
Enter precision: 4
3.1416
Chapter 22. <stdio.h> Standard I/O Library 224
<< 3490>>
<<3490 >>
Like with the precision, you can use an asterisk (*) as the field width
int field_width;
int val = 3490;
22.10.0.6 Flags
Before the field width, you can put some optional flags that further control the output of the subsequent fields.
We just saw that the - flag can be used to left- or right-justify fields. But there are plenty more!
Flag Description
- For a field width, left justify in the field (right is default).
+ If the number is signed, always prefix a + or - on the front.
[SPACE] If the number is signed, prefix a space for positive, or a - for negative.
0 Pad the right-justified field with leading zeros instead of leading spaces.
# Print using an alternate form. See below.
For example, we could pad a hexadecimal number with leading zeros to a field width of 8 with:
printf("%08x\n", 0x1234); // 00001234
Return Value
Returns the number of characters outputted, or a negative number on error.
Example
1 #include <stdio.h>
2
3 int main(void)
4 {
5 int a = 100;
6 float b = 2.717;
7 char *c = "beej!";
8 char d = 'X';
9 int e = 5;
10
See Also
sprintf(), vprintf()
Synopsis
#include <stdio.h>
Description
These functions read formatted output from a variety of sources.
The only differences between these is are the leading parameters that you pass to them before the format
string.
The scanf() family of functions reads data from the console or from a FILE stream, parses it, and stores
the results away in variables you provide in the argument list.
The format string is very similar to that in printf() in that you can tell it to read a "%d", for instance for an
int. But it also has additional capabilities, most notably that it can eat up other characters in the input that
you specify in the format string.
But let’s start simple, and look at the most basic usage first before plunging into the depths of the function.
We’ll start by reading an int from the keyboard:
int a;
scanf("%d", &a);
scanf() obviously needs a pointer to the variable if it is going to change the variable itself, so we use the
address-of operator to get the pointer.
In this case, scanf() walks down the format string, finds a “%d”, and then knows it needs to read an integer
and store it in the next variable in the argument list, a.
Here are some of the other format specifiers you can put in the format string:
In that case, scanf() will attempt to consume an unsigned decimal number, then a hyphen, then another
unsigned number, then another hypen, then another unsigned number.
If it fails to match at any point (e.g. the user entered “foo”), scanf() will bail without consuming the offend-
ing characters.
And it will return the number of variables successfully converted. In the example above, if the user entered
a valid string, scanf() would return 3, one for each variable successfully read.
Conversion
Specifier Description
d Matches a decimal int. Can have a leading sign.
i Like d, except will handle it if you put a leading 0x (hex) or 0 (octal) on the number.
o Matches an octal (base 8) unsigned int. Leading zeros are ignored.
u Matches a decimal unsigned int.
x Matches a hex (base 16) unsigned int.
f Match a floating point number (or scientific notation, or anything strtod() can handle).
c Match a char, or mutiple chars if a field width is given.
s Match a sequence of non-whitespace chars.
[ Match a sequence of characters from a set. The set ends with ]. More below.
p Match a pointer, the opposite of %p for printf().
n Store the number of characters written so far in the given int*. Doesn’t consume
anything.
% Match a literal percent sign.
22.11.0.5.1 The Scanset %[] Conversion Specifier This is about the weirdest format specifier there is.
It allows you to specify a set of characters (the scanset) to be stored away (likely in an array of chars).
Conversion stops when a character that is not in the set is matched.
Chapter 22. <stdio.h> Standard I/O Library 229
For example, %[0-9] means “match all numbers zero through nine.” And %[AD-G34] means “match A, D
through G, 3, or 4”.
Now, to convolute matters, you can tell scanf() to match characters that are not in the set by putting a caret
(^) directly after the %[ and following it with the set, like this: %[^A-C], which means “match all characters
that are not A through C.”
To match a close square bracket, make it the first character in the set, like this: %[]A-C] or %[^]A-C]. (I
added the “A-C” just so it was clear that the “]” was first in the set.)
To match a hyphen, make it the last character in the set, e.g. to match A-through-C or hyphen: %[A-C-].
So if we wanted to match all letters except “%”, “^”, “]”, “B”, “C”, “D”, “E”, and “-”, we could use this
format string: %[^]%^B-E-].
Got it? Now we can go onto the next func—no wait! There’s more! Yes, still more to know about scanf().
Does it never end? Try to imagine how I feel writing about it!
Length
Modifier Conversion Specifier Description
hh d, i, o, u, x, X Convert input to char (signed or unsigned as appropriate)
before printing.
h d, i, o, u, x, X Convert input to short int (signed or unsigned as
appropriate) before printing.
l d, i, o, u, x, X Convert input to long int (signed or unsigned as
appropriate).
ll d, i, o, u, x, X Convert input to long long int (signed or unsigned as
appropriate).
j d, i, o, u, x, X Convert input to intmax_t or uintmax_t (as appropriate).
z d, i, o, u, x, X Convert input to size_t.
t d, i, o, u, x, X Convert input to ptrdiff_t.
L a, A, e, E, f, F, g, G Convert input to long double.
l c,s,[ Convert input to wchar_t, a wide character.
l s Argument is in a wchar_t*, a wide character string.
hh n Store result in signed char* argument.
h n Store result in short int* argument.
l n Store result in long int* argument.
ll n Store result in long long int* argument.
j n Store result in intmax_t* argument.
z n Store result in size_t* argument.
t n Store result in ptrdiff_t* argument.
And a float will stop being consumed at the end of the number, even if fewer characters than the field width
are matched.
But %c is an interesting one—it doesn’t stop consuming characters on anything. So it’ll go exactly to the
field width. (Or 1 character if no field width is given.)
Return Value
scanf() returns the number of items assigned into variables. Since assignment into variables stops when
given invalid input for a certain format specifier, this can tell you if you’ve input all your data correctly.
Also, scanf() returns EOF on end-of-file.
Example
1 #include <stdio.h>
2
3 int main(void)
4 {
5 int a;
6 long int b;
7 unsigned int c;
8 float d;
9 double e;
10 long double f;
11 char s[100];
12
31 // store 10 characters:
Chapter 22. <stdio.h> Standard I/O Library 231
32 scanf("%10c", s);
33 }
See Also
sscanf(), vscanf(), vsscanf(), vfscanf()
Synopsis
#include <stdio.h>
#include <stdarg.h>
Description
These are just like the printf() variants except instead of taking an actual variable number of arguments,
they take a fixed number—the last of which is a va_list that refers to the variable arguments.
Like with printf(), the different variants send output different places.
Both vsprintf() and vsnprintf() have the quality that if you pass in NULL as the buffer, nothing is
written—but you can still check the return value to see how many characters would have been written.
If you try to write out more than the maximum number of characters, vsnprintf() will graciously write
only 𝑛 − 1 characters so that it has enough room to write the terminator at the end.
As for why in the heck would you ever want to do this, the most common reason is to create your own
specialized versions of printf()-type functions, piggybacking on all that printf() functionality goodness.
See the example for an example, predictably.
Chapter 22. <stdio.h> Standard I/O Library 232
Return Value
vprintf() and vfprintf() return the number of characters printed, or a negative value on error.
vsprintf() returns the number of characters printed to the buffer, not counting the NUL terminator, or a
negative value if an error occurred.
vnsprintf() returns the number of characters printed to the buffer. Or the number that would have been
printed if the buffer had been large enough.
Example
In this example, we make our own version of printf() called logger() that timestamps output. Notice
how the calls to logger() have all the bells and whistles of printf().
1 #include <stdio.h>
2 #include <stdarg.h>
3 #include <time.h>
4
16 va_start(va, format);
17 int result = vprintf(format, va);
18 va_end(va);
19
20 printf("\n");
21
22 return result;
23 }
24
25 int main(void)
26 {
27 int x = 12;
28 float y = 3.2;
29
30 logger("Hello!");
31 logger("x = %d and y = %.2f", x, y);
32 }
Output:
2021-03-30 04:25:49 : Hello!
2021-03-30 04:25:49 : x = 12 and y = 3.20
See Also
printf()
Chapter 22. <stdio.h> Standard I/O Library 233
Synopsis
#include <stdio.h>
#include <stdarg.h>
Description
These are just like the scanf() variants except instead of taking an actual variable number of arguments,
they take a fixed number—the last of which is a va_list that refers to the variable arguments.
Like with the vprintf() functions, this would be a good way to add additional functionality that took
advantage of the power scanf() has to offer.
Return Value
Returns the number of items successfully scanned, or EOF on end-of-file or error.
Example
I have to admit I was wracking my brain to think of when you’d ever want to use this. The best example I
could find was one on Stack Overflow4 that error-checks the return value from scanf() against the expected.
A variant of that is shown below.
1 #include <stdio.h>
2 #include <stdarg.h>
3 #include <assert.h>
4
4
https://stackoverflow.com/questions/17017331/c99-vscanf-for-dummies/17018046#17018046
Chapter 22. <stdio.h> Standard I/O Library 234
9 va_start(va, format);
10 int count = vscanf(format, va);
11 va_end(va);
12
16 return count;
17 }
18
19 int main(void)
20 {
21 int a, b;
22 float c;
23
See Also
scanf()
Synopsis
#include <stdio.h>
int getchar(void);
Description
All of these functions in one way or another, read a single character from the console or from a FILE. The
differences are fairly minor, and here are the descriptions:
getc() returns a character from the specified FILE. From a usage standpoint, it’s equivalent to the same
fgetc() call, and fgetc() is a little more common to see. Only the implementation of the two functions
differs.
fgetc() returns a character from the specified FILE. From a usage standpoint, it’s equivalent to the same
getc() call, except that fgetc() is a little more common to see. Only the implementation of the two
functions differs.
Yes, I cheated and used cut-n-paste to do that last paragraph.
getchar() returns a character from stdin. In fact, it’s the same as calling getc(stdin).
Chapter 22. <stdio.h> Standard I/O Library 235
Return Value
All three functions return the unsigned char that they read, except it’s cast to an int.
If end-of-file or an error is encountered, all three functions return EOF.
Example
This example reads all the characters from a file, outputting only the letter ’b’s it finds..
1 #include <stdio.h>
2
3 int main(void)
4 {
5 FILE *fp;
6 int c;
7
18 putchar('\n');
19
20 fclose(fp);
21 }
See Also
Synopsis
#include <stdio.h>
Description
These are functions that will retrieve a newline-terminated string from the console or a file. In other normal
words, it reads a line of text. The behavior is slightly different, and, as such, so is the usage. For instance,
here is the usage of gets():
Don’t use gets(). In fact, as of C11, it ceases to exist! This is one of the rare cases of a function being
removed from the standard.
Chapter 22. <stdio.h> Standard I/O Library 236
Admittedly, rationale would be useful, yes? For one thing, gets() doesn’t allow you to specify the length
of the buffer to store the string in. This would allow people to keep entering data past the end of your buffer,
and believe me, this would be Bad News.
And that’s what the size parameter in fgets() is for. fgets() will read at most size-1 characters and
then stick a NUL terminator on after that.
I was going to add another reason, but that’s basically the primary and only reason not to use gets(). As
you might suspect, fgets() allows you to specify a maximum string length.
One difference here between the two functions: gets() will devour and throw away the newline at the end
of the line, while fgets() will store it at the end of your string (space permitting).
Here’s an example of using fgets() from the console, making it behave more like gets() (with the excep-
tion of the newline inclusion):
char s[100];
gets(s); // don't use this--read a line (from stdin)
fgets(s, sizeof(s), stdin); // read a line from stdin
In this case, the sizeof() operator gives us the total size of the array in bytes, and since a char is a byte, it
conveniently gives us the total size of the array.
Of course, like I keep saying, the string returned from fgets() probably has a newline at the end that you
might not want. You can write a short function to chop the newline off—in fact, let’s just roll that into our
own version of gets()
#include <stdio.h>
#include <string.h>
if (rv == NULL)
return NULL;
return s;
}
So, in summary, use fgets() to read a line of text from the keyboard or a file, and don’t use gets().
Return Value
Both gets() and fgets() return a pointer to the string passed.
On error or end-of-file, the functions return NULL.
Example
1 #include <stdio.h>
2
3 int main(void)
Chapter 22. <stdio.h> Standard I/O Library 237
4 {
5 FILE *fp;
6 char s[100];
7
See Also
getc(), fgetc(), getchar(), puts(), fputs(), ungetc()
Synopsis
#include <stdio.h>
Description
All three functions output a single character, either to the console or to a FILE.
putc() takes a character argument, and outputs it to the specified FILE. fputc() does exactly the same
thing, and differs from putc() in implementation only. Most people use fputc().
putchar() writes the character to the console, and is the same as calling putc(c, stdout).
Return Value
All three functions return the character written on success, or EOF on error.
Example
Print the alphabet:
Chapter 22. <stdio.h> Standard I/O Library 238
1 #include <stdio.h>
2
3 int main(void)
4 {
5 char i;
6
See Also
Synopsis
#include <stdio.h>
Description
Both these functions output a NUL-terminated string. puts() outputs to the console, while fputs() allows
you to specify the file for output.
Return Value
Both functions return non-negative on success, or EOF on error.
Example
Read strings from the console and save them in a file:
1 #include <stdio.h>
2
3 int main(void)
4 {
5 FILE *fp;
6 char s[100];
7
12 }
13
14 fclose(fp);
15 }
See Also
22.18 ungetc()
Pushes a character back into the input stream
Synopsis
#include <stdio.h>
Description
You know how getc() reads the next character from a file stream? Well, this is the opposite of that—it
pushes a character back into the file stream so that it will show up again on the very next read from the
stream, as if you’d never gotten it from getc() in the first place.
Why, in the name of all that is holy would you want to do that? Perhaps you have a stream of data that
you’re reading a character at a time, and you won’t know to stop reading until you get a certain character,
but you want to be able to read that character again later. You can read the character, see that it’s what you’re
supposed to stop on, and then ungetc() it so it’ll show up on the next read.
Yeah, that doesn’t happen very often, but there we are.
Here’s the catch: the standard only guarantees that you’ll be able to push back one character. Some imple-
mentations might allow you to push back more, but there’s really no way to tell and still be portable.
Return Value
On success, ungetc() returns the character you passed to it. On failure, it returns EOF.
Example
This example reads a piece of punctuation, then everything after it up to the next piece of punctuation. It
returns the leading punctuation, and stores the rest in a string.
1 #include <stdio.h>
2 #include <ctype.h>
3
8 origpunct = fgetc(fp);
9
11 return EOF;
12
23 return origpunct;
24 }
25
26 int main(void)
27 {
28 char s[128];
29 char c;
30
Sample Input:
!foo#bar*baz
Sample output:
!: foo
#: bar
*: baz
See Also
fgetc()
22.19 fread()
Read binary data from a file
Synopsis
#include <stdio.h>
Description
You might remember that you can call fopen() with the “b” flag in the open mode string to open the file in
“binary” mode. Files open in not-binary (ASCII or text mode) can be read using standard character-oriented
Chapter 22. <stdio.h> Standard I/O Library 241
calls like fgetc() or fgets(). Files open in binary mode are typically read using the fread() function.
All this function does is says, “Hey, read this many things where each thing is a certain number of bytes, and
store the whole mess of them in memory starting at this pointer.”
This can be very useful, believe me, when you want to do something like store 20 ints in a file.
But wait—can’t you use fprintf() with the “%d” format specifier to save the ints to a text file and store
them that way? Yes, sure. That has the advantage that a human can open the file and read the numbers. It
has the disadvantage that it’s slower to convert the numbers from ints to text and that the numbers are likely
to take more space in the file. (Remember, an int is likely 4 bytes, but the string “12345678” is 8 bytes.)
So storing the binary data can certainly be more compact and faster to read.
Return Value
This function returns the number of items successfully read. If all requested items are read, the return value
will be equal to that of the parameter nmemb. If EOF occurs, the return value will be zero.
To make you confused, it will also return zero if there’s an error. You can use the functions feof() or
ferror() to tell which one really happened.
Example
Read 10 numbers from a file and store them in an array:
1 #include <stdio.h>
2
3 int main(void)
4 {
5 int i;
6 int n[10]
7 FILE *fp;
8
9 fp = fopen("numbers.dat", "rb");
10 fread(n, sizeof(int), 10, fp); // read 10 ints
11 fclose(fp);
12
See Also
fopen(), fwrite(), feof(), ferror()
22.20 fwrite()
Write binary data to a file
Synopsis
Chapter 22. <stdio.h> Standard I/O Library 242
#include <stdio.h>
size_t fwrite(const void *p, size_t size, size_t nmemb, FILE *stream);
Description
This is the counterpart to the fread() function. It writes blocks of binary data to disk. For a description of
what this means, see the entry for fread().
Return Value
fwrite() returns the number of items successfully written, which should hopefully be nmemb that you passed
in. It’ll return zero on error.
Example
Save 10 random numbers to a file:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(void)
5 {
6 int i;
7 int n[10];
8 FILE *fp;
9
See Also
fopen(), fread()
Synopsis
Chapter 22. <stdio.h> Standard I/O Library 243
#include <stdio.h>
Description
These functions are just like ftell() and fseek(), except instead of counting in bytes, they use an opaque
data structure to hold positional information about the file. (Opaque, in this case, means you’re not supposed
to know what the data type is made up of.)
On virtually every system (and certainly every system that I know of), people don’t use these functions, using
ftell() and fseek() instead. These functions exist just in case your system can’t remember file positions
as a simple byte offset.
Since the pos variable is opaque, you have to assign to it using the fgetpos() call itself. Then you save the
value for later and use it to reset the position using fsetpos().
Return Value
Both functions return zero on success, and -1 on error.
Example
1 #include <stdio.h>
2
3 int main(void)
4 {
5 char s[100];
6 fpos_t pos;
7 FILE *fp;
8
9 fp = fopen("spoon.txt", "r");
10
24 fclose(fp);
25 }
Chapter 22. <stdio.h> Standard I/O Library 244
See Also
fseek(), ftell(), rewind()
Synopsis
#include <stdio.h>
Description
When doing reads and writes to a file, the OS keeps track of where you are in the file using a counter
generically known as the file pointer. You can reposition the file pointer to a different point in the file using
the fseek() call. Think of it as a way to randomly access you file.
The first argument is the file in question, obviously. offset argument is the position that you want to seek
to, and whence is what that offset is relative to.
Of course, you probably like to think of the offset as being from the beginning of the file. I mean, “Seek to
position 3490, that should be 3490 bytes from the beginning of the file.” Well, it can be, but it doesn’t have
to be. Imagine the power you’re wielding here. Try to command your enthusiasm.
You can set the value of whence to one of three things:
whence Description
SEEK_SET offset is relative to the beginning of the file. This is probably what you had in mind
anyway, and is the most commonly used value for whence.
SEEK_CUR offset is relative to the current file pointer position. So, in effect, you can say, “Move
to my current position plus 30 bytes,” or, “move to my current position minus 20 bytes.”
SEEK_END offset is relative to the end of the file. Just like SEEK_SET except from the other end of
the file. Be sure to use negative values for offset if you want to back up from the end
of the file, instead of going past the end into oblivion.
Speaking of seeking off the end of the file, can you do it? Sure thing. In fact, you can seek way off the end
and then write a character; the file will be expanded to a size big enough to hold a bunch of zeros way out to
that character.
Now that the complicated function is out of the way, what’s this rewind() that I briefly mentioned? It
repositions the file pointer at the beginning of the file:
fseek(fp, 0, SEEK_SET); // same as rewind()
rewind(fp); // same as fseek(fp, 0, SEEK_SET)
Chapter 22. <stdio.h> Standard I/O Library 245
Return Value
For fseek(), on success zero is returned; -1 is returned on failure.
The call to rewind() never fails.
Example
1 #include <stdio.h>
2
3 int main(void)
4 {
5 FILE *fp;
6
7 fp = fopen("spoon.txt", "r");
8
12 fseek(fp, -31, SEEK_CUR); // seek backward 30 bytes from the current pos
13 printf("31 back: %c\n", fgetc(fp));
14
15 fseek(fp, -12, SEEK_END); // seek to the 10th byte before the end of file
16 printf("12 from end: %c\n", fgetc(fp));
17
22 fclose(fp);
23 }
See Also
ftell(), fgetpos(), fsetpos()
22.23 ftell()
Tells you where a particular file is about to read from or write to
Synopsis
#include <stdio.h>
Description
This function is the opposite of fseek(). It tells you where in the file the next file operation will occur
relative to the beginning of the file.
Chapter 22. <stdio.h> Standard I/O Library 246
It’s useful if you want to remember where you are in the file, fseek() somewhere else, and then come back
later. You can take the return value from ftell() and feed it back into fseek() (with whence parameter
set to SEEK_SET) when you want to return to your previous position.
Return Value
Returns the current offset in the file, or -1 on error.
Example
1 #include <stdio.h>
2
3 int main(void)
4 {
5 char c[6];
6 FILE *fp;
7
8 fp = fopen("spoon.txt", "r");
9
10 long pos;
11
31 fclose(fp);
32 }
See Also
fseek(), rewind(), fgetpos(), fsetpos()
Synopsis
#include <stdio.h>
Description
Each FILE* that you use to read and write data from and to a file contains flags that the system sets when
certain events occur. If you get an error, it sets the error flag; if you reach the end of the file during a read, it
sets the EOF flag. Pretty simple really.
The functions feof() and ferror() give you a simple way to test these flags: they’ll return non-zero (true)
if they’re set.
Once the flags are set for a particular stream, they stay that way until you call clearerr() to clear them.
Return Value
feof() and ferror() return non-zero (true) if the file has reached EOF or there has been an error, respec-
tively.
Example
Read binary data, checking for EOF or error:
1 #include <stdio.h>
2
3 int main(void)
4 {
5 int a;
6 FILE *fp;
7
8 fp = fopen("numbers.dat", "r");
9
16 if (feof(fp))
17 printf("End of file was reached.\n");
18
19 if (ferror(fp))
20 printf("An error occurred.\n");
21
22 fclose(fp);
23 }
Chapter 22. <stdio.h> Standard I/O Library 248
See Also
fopen(), fread()
22.25 perror()
Print the last error message to stderr
Synopsis
#include <stdio.h>
#include <errno.h> // only if you want to directly use the "errno" var
Description
Many functions, when they encounter an error condition for whatever reason, will set a global variable called
errno (in <errno.h>) for you. errno is just an interger representing a unique error.
But to you, the user, some number isn’t generally very useful. For this reason, you can call perror() after
an error occurs to print what error has actually happened in a nice human-readable string.
And to help you along, you can pass a parameter, s, that will be prepended to the error string for you.
One more clever trick you can do is check the value of the errno (you have to include errno.h to see it)
for specific errors and have your code do different things. Perhaps you want to ignore certain errors but not
others, for instance.
The standard only defines three values for errno, but your system undoubtedly defines more. The three that
are defined are:
errno Description
EDOM Math operation outside domain.
EILSEQ Invalid sequence in multibyte to wide character encoding.
ERANGE Result of operation doesn’t fit in specified type.
The catch is that different systems define different values for errno, so it’s not very portable beyond the
above 3. The good news is that at least the values are largely portable between Unix-like systems, at least.
Return Value
Returns nothing at all! Sorry!
Example
fseek() returns -1 on error, and sets errno, so let’s use it. Seeking on stdin makes no sense, so it should
generate an error:
1 #include <stdio.h>
2 #include <errno.h> // must include this to see "errno" in this example
3
4 int main(void)
Chapter 22. <stdio.h> Standard I/O Library 249
5 {
6 if (fseek(stdin, 10L, SEEK_SET) < 0)
7 perror("fseek");
8
17 if (errno == EBADF) {
18 perror("fseek again, EBADF");
19 } else {
20 perror("fseek again");
21 }
22 }
23 }
See Also
feof(), ferror(), strerror()
Chapter 23
Some of the following functions have variants that handle different types: atoi(), strtod(), strtol(),
abs(), and div(). Only a single one is listed here for brevity.
Function Description
_Exit() Exit the currently-running program and don’t look back
abort() Abruptly end program execution
abs() Compute the absolute value of an integer
aligned_alloc() Allocate specifically-aligned memory
at_quick_exit() Set up handlers to run when the program quickly exits
atexit() Set up handlers to run when the program exits
atof() Convert a string to a floating point value
atoi() Convert an integer in a string into a integer type
bsearch() Binary Search (maybe) an array of objects
calloc() Allocate and clear memory for arbitrary use
div() Compute the quotient and remainder of two numbers
exit() Exit the currently-running program
free() Free a memory region
getenv() Get the value of an environment variable
malloc() Allocate memory for arbitrary use
mblen() Return the number of bytes in a multibyte character
mbstowcs() Convert a multibyte string to a wide character string
mbtowc() Convert a multibyte character to a wide character
qsort() Quicksort (maybe) some data
quick_exit() Exit the currently-running program quickly
rand() Return a pseudorandom number
realloc() Resize a previously allocated stretch of memory
srand() Seed the built-in pseudorandom number generator
strtod() Convert a string to a floating point number
strtol() Convert a string to an integer
system() Run an external program
wcstombs() Convert a wide character string to a multibyte string
wctomb() Convert a wide character to a multibyte character
The <stdlib.h> header has all kinds of—dare I say—miscellaneous functions bundled into it. This func-
250
Chapter 23. <stdlib.h> Standard Library Functions 251
tionality includes:
• Conversions from numbers to strings
• Conversions from strings to numbers
• Pseudorandom number generation
• Dynamic memory allocation
• Various ways to exit the program
• Ability to run external programs
• Binary search (or some fast search)
• Quicksort (or some fast sort)
• Integer arithmetic functions
• Multibyte and wide character and string conversions
So, you know… a little of everything.
Type Description
size_t Returned from sizeof and used elsewhere
wchar_t For wide character operations
div_t For the div() function
ldiv_t For the ldiv() function
lldiv_t for the lldiv() function
Type Description
NULL Our good pointer friend
EXIT_SUCCESS Good exit status when things go well
EXIT_FAILURE Good exit status when things go poorly
RAND_MAX The maximum value that can be returned by the
rand() function
MB_CUR_MAX Maximum number of bytes in a multibyte character
in the current locale
And there you have it. Just a lot of fun, useful functions in here. Let’s check ’em out!
23.2 atof()
Convert a string to a floating point value
Synopsis
#include <stdlib.h>
Description
This stood for “ASCII-To-Floating” back in the day1 , but no one would dare to use such coarse language
now.
But the gist is the same: we’re going to convert a string with numbers and (optionally) a decimal point into
a floating point value. Leading whitespace is ignored, and translation stops at the first invalid character.
If the result doesn’t fit in a double, behavior is undefined.
It generally works as if you’d called strtod():
strtod(nptr, NULL)
Return Value
Returns the string converted to a double.
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(void)
5 {
6 double x = atof("3.141593");
7
See Also
atoi(), strtod()
Synopsis
#include <stdlib.h>
1
http://man.cat-v.org/unix-1st/3/atof
Chapter 23. <stdlib.h> Standard Library Functions 253
Description
Back in the day, atoi() stood for “ASCII-To_Integer”2 but now the spec makes no mention of that.
These functions take a string with a number in them and convert it to an integer of the specified return type.
Leading whitespace is ignored. Translation stops at the first invalid character.
If the result doesn’t fit in the return type, behavior is undefined.
It generally works as if you’d called strtol() family of functions:
atoi(nptr) // is basically the same as...
(int)strtol(nptr, NULL, 10)
Again, the strtol() functions are generally better, so I recommend them instead of these.
Return Value
Returns an integer result corresponding to the return type.
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(void)
5 {
6 int x = atoi("3490");
7
See Also
atof(), strtol()
Synopsis
#include <stdlib.h>
2
http://man.cat-v.org/unix-1st/3/atoi
Chapter 23. <stdlib.h> Standard Library Functions 254
Description
These are some neat functions that convert strings to floating point numbers (or even NaN or Infinity) and
provide some error checking, besides.
Firstly, leading whitespace is skipped.
Then the functions attempt to convert characters into the floating point result. Finally, when an invalid
character (or NUL character) is reached, they set endptr to point to the invalid character.
Set endptr to NULL if you don’t care about where the first invalid character is.
If you didn’t set endptr to NULL, it will point to a NUL character if the translation didn’t find any bad
characters. That is:
if (*endptr == '\0') {
printf("What a perfectly-formed number!\n");
} else {
printf("I found badness in your number: \"%s\"\n", endptr);
}
But guess what! You can also translate strings into special values, like NaN and Infinity!
If nptr points to a string containing INF or INFINITY (upper or lowercase), the value for Infinity will be
returned.
If nptr points to a string containing NAN, then (a quiet, non-signalling) NaN will be returned. You can tag
the NAN with a sequence of characters from the set 0-9, a-z, A-Z, and _ by enclosing them in parens:
NAN(foobar_3490)
What your compiler does with this is implementation-defined, but it can be used to specify different kinds of
NaN.
You can also specify a number in hexadecimal with a power-of-two exponent (2𝑥 ) if you lead with 0x (or
0X). For the exponent, use a p followed by a base 10 exponent. (You can’t use e because that’s a valid hex
digit!)
Example:
0xabc.123p15
Return Value
Returns the converted number. If there was no number, returns 0. endptr is set to point to the first invalid
character, or the NUL terminator if all characters were consumed.
If there’s an overflow, HUGE_VAL, HUGE_VALF, or HUGE_VALL is returned, signed like the input, and errno
is set to ERANGE.
If there’s an underflow, it returns the smallest number closest to zero with the input sign. errno may be set
to ERANGE.
Chapter 23. <stdlib.h> Standard Library Functions 255
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(void)
5 {
6 char *inp = " 123.4567beej";
7 char *badchar;
8
19 if (*badchar == '\0')
20 printf("No bad chars: %f\n", val);
21 else
22 printf("Found bad chars: %f, %s\n", val, badchar);
23 }
Output:
Converted string to 123.456700
Encountered bad characters: beej
Ignoring bad chars: 987.654321
No bad chars: 11.223300
See Also
atof(), strtol()
Synopsis
#include <stdlib.h>
Description
These convert a string to an integer like atoi(), but they have a few more bells and whistles.
Most notable, they can tell you where conversion started going wrong, i.e. where invalid characters, if any,
appear. Leading spaces are ignored. A + or - sign may precede the number.
The basic idea is that if things go well, these functions will return the integer values contained in the strings.
And if you pass in the char** typed endptr, it’ll set it to point at the NUL at the end of the string.
If things don’t go well, they’ll set endptr to point at the first character where things have gone awry. That
is, if you’re converting a value 103z2! in base 10, they’ll send endptr to point at the z because that’s the
first non-numeric character.
You can pass in NULL for endptr if you don’t care to do any of that kind of error checking.
Wait—did I just say we could set the number base for the conversion? Yes! Yes, I did. Now number bases3
are out of scope for this document, but certainly some of the more well-known are binary (base 2), octal
(base 8), decimal (base 10), and hexadecimal (base 16).
You can specify the number base for the conversion as the third parameter. Bases from 2 to 36 are supported,
with case-insensitive digits running from 0 to Z.
If you specify a base of 0, the function will make an effort to determine it. It’ll default to base 10 except for
a couple cases:
• If the number has a leading 0, it will be octal (base 8)
• If the number has a leading 0x or 0X, it will be hex (base 16)
The locale might affect the behavior of these functions.
Return Value
Returns the converted value.
endptr, if not NULL is set to the first invalid character, or to the beginning of the string if no conversion was
performed, or to the string terminal NUL if all characters were valid.
If there’s overflow, one of these values will be returned: LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX,
ULONG_MAX, ULLONG_MAX. And errno is set to ERANGE.
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(void)
5 {
6 // All output in decimal (base 10)
7
3
https://en.wikipedia.org/wiki/Radix
Chapter 23. <stdlib.h> Standard Library Functions 257
17 char *badchar;
18 long int x = strtol(" 1234beej", &badchar, 0);
19
Output:
123
123
42
83
291
83
291
Value is 1234
Bad chars at "beej"
See Also
atoi(), strtod(), setlocale(), strtoimax(), strtoumax()
23.6 rand()
Return a pseudorandom number
Synopsis
#include <stdlib.h>
int rand(void);
Description
This gives us back a pseudorandom number in the range 0 to RAND_MAX, inclusive. (RAND_MAX will be at
least 32767.)
If you want to force this to a certain range, the classic way to do this is to force it with the modulo operator %,
although this introduces biases4 if RAND_MAX+1 is not a multiple of the number you’re modding by. Dealing
with this is out of scope for this guide.
4
https://stackoverflow.com/questions/10984974/why-do-people-say-there-is-modulo-bias-when-using-a-random-number-
generator
Chapter 23. <stdlib.h> Standard Library Functions 258
If you want to to make a floating point number between 0 and 1 inclusive, you can divide the result by
RAND_MAX. Or RAND_MAX+1 if you don’t want to include 1. But of course, there are out-of-scope problems
with this, as well5 .
In short, rand() is a great way to get potentially poor random numbers with ease. Probably good enough
for the game you’re writing.
The spec elaborates:
There are no guarantees as to the quality of the random sequence produced and some implemen-
tations are known to produce sequences with distressingly non-random low-order bits. Applica-
tions with particular requirements should use a generator that is known to be sufficient for their
needs.
Your system probably has a good random number generator on it if you need a stronger source. Linux users
have getrandom(), for example, and Windows has CryptGenRandom().
For other more demanding random number work, you might find a library like the GNU Scientific Library6
of use.
With most implementations, the numbers produced by rand() will be the same from run to run. To get
around this, you need to start it off in a different place by passing a seed into the random number generator.
You can do this with srand().
Return Value
Returns a random number in the range 0 to RAND_MAX, inclusive.
Example
Note that all of these examples don’t produce perfectly uniform distributions. But good enough for the
untrained eye, and really common in general use when mediocre random number quality is acceptable.
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(void)
5 {
6 printf("RAND_MAX = %d\n", RAND_MAX);
7
Output on my system:
RAND_MAX = 2147483647
0 to 9: 3
10 to 44: 21
0 to 0.99999: 0.783099
10.5 to 15.7: 14.651888
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <time.h>
4
5 int main(void)
6 {
7 // time(NULL) very likely returns the number of seconds since
8 // January 1, 1970:
9
10 srand(time(NULL));
11
See Also
srand()
23.7 srand()
Seed the built-in pseudorandom number generator
Synopsis
#include <stdlib.h>
Description
The dirty little secret of pseudorandom number generation is that they’re completely deterministic. There’s
nothing random about them. They just look random.
If you use rand() and run your program several times, you might notice something fishy: they produce the
same random numbers over and over again.
To mix it up, we need to give the pseudorandom number generator a new “starting point”, if you will. We
call that the seed. It’s just a number, but it is used as the basic for subsequent number generation. Give a
different seed, and you’ll get a different sequence of random numbers. Give the same seed, and you’ll get
the same sequence of random numbers corresponding to it7 .
So if you call srand(3490) before you start generating numbers with rand(), you’ll get the same sequence
every time. srand(37) would also give you the same sequence every time, but it would be a different
sequence than the one you got with srand(3490).
But if you can’t hardcode the seed (because that would give you the same sequence every time), how are you
supposed to do this?
7
Minecraft enthusiasts might recall that when generating a new world, they were given the option to enter a random number seed.
That single value is used to generate that entire random world. And if your friend starts a world with the same seed you did, they’ll get
the same world you did.
Chapter 23. <stdlib.h> Standard Library Functions 260
It’s really common to use the number of seconds since January 1, 1970 (this date is known as the Unix
epoch8 ) to seed the generator. This sounds pretty arbitrary except for the fact that it’s exactly the value most
implementations return from the library call time(NULL)9 .
We’ll do that in the example.
If you don’t call srand(), it’s as if you called srand(1).
Return Value
Returns nothing!
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <time.h> // for the time() call
4
5 int main(void)
6 {
7 srand(time(NULL));
8
Output:
4
20
22
14
9
See Also
rand(), time()
23.8 aligned_alloc()
Allocate specifically-aligned memory
8
https://en.wikipedia.org/wiki/Unix_time
9
The C spec doesn’t say exactly what time(NULL) will return, but the POSIX spec does! And virtually everyone returns exactly
that: the number of seconds since epoch.
Chapter 23. <stdlib.h> Standard Library Functions 261
Synopsis
#include <stdlib.h>
Description
Maybe you wanted malloc() or calloc() instead of this. But if you’re sure you don’t, read on!
Normally you don’t have to think about this, since malloc() and realloc() both provide memory regions
that are suitably aligned10 for use with any data type.
But if you need a more specific alignment, you can specify it with this function.
When you’re done using the memory region, be sure to free it with a call to free().
Don’t pass in 0 for the size. It probably won’t do anything you want.
In case you’re wondering, all dynamically-allocated memory is automatically freed by the system when the
program ends. That said, it’s considered to be Good Form to explicitly free() everything you allocate. This
way other programmers don’t think you were being sloppy.
Return Value
Returns a pointer to the newly-allocated memory, aligned as specified. Returns NULL if something goes
wrong.
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4
5 int main(void)
6 {
7 int *p = aligned_alloc(256, 10 * sizeof(int));
8
9 // Just for fun, let's convert to intptr_t and mod with 256
10 // to make sure we're actually aligned on a 256-byte boundary.
11 //
12 // This is probably some kind of implementation-defined
13 // behavior, but I'll bet it works.
14
15 intptr_t ip = (intptr_t)p;
16
17 printf("%ld\n", ip % 256); // 0!
18
19 // Free it up
20 free(p);
21 }
10
https://en.wikipedia.org/wiki/Data_structure_alignment
Chapter 23. <stdlib.h> Standard Library Functions 262
See Also
malloc(), calloc(), free()
Synopsis
#include <stdlib.h>
Description
Both of these functions allocate memory for general-purpose use. It will be aligned such that it’s useable for
storing any data type.
malloc() allocates exactly the specified number of bytes of memory in a contiguous block. The memory
might be full of garbage data. (You can clear it with memset(), if you wish.)
calloc() is different in that it allocates space for nmemb objects of size bytes each. (You can do the same
with malloc(), but you have to do the multiplication yourself.)
calloc() has an additional feature: it clears all the memory to 0.
So if you’re planning to zero the memory anyway, calloc() is probably the way to go. If you’re not, you
can avoid that overhead by calling malloc().
When you’re done using the memory region, free it with a call to free().
Don’t pass in 0 for the size. It probably won’t do anything you want.
In case you’re wondering, all dynamically-allocated memory is automatically freed by the system when the
program ends. That said, it’s considered to be Good Form to explicitly free() everything you allocate. This
way other programmers don’t think you were being sloppy.
Return Value
Both functions return a pointer to the shiny, newly-allocated memory. Or NULL if something’s gone awry.
Example
Comparison of malloc() and calloc() for allocating 5 ints:
1 #include <stdlib.h>
2
3 int main(void)
4 {
5 // Allocate space for 5 ints
6 int *p = malloc(5 * sizeof(int));
7
8 p[0] = 12;
Chapter 23. <stdlib.h> Standard Library Functions 263
9 p[1] = 30;
10
15 q[0] = 12;
16 q[1] = 30;
17
18 // All done
19 free(p);
20 free(q);
21 }
See Also
aligned_alloc(), free()
23.10 free()
Free a memory region
Synopsis
#include <stdlib.h>
Description
You know that pointer you got back from malloc(), calloc(), or aligned_alloc()? You pass that
pointer to free() to free the memory associated with it.
If you don’t do this, the memory will stay allocated FOREVER AND EVER! (Well, until your program exits,
anyway.)
Fun fact: free(NULL) does nothing. You can safely call that. Sometimes it’s convenient.
Don’t free() a pointer that’s already been free()d. Don’t free() a pointer that you didn’t get back from
one of the allocation functions. It would be Bad11 .
Return Value
Returns nothing!
Example
1 #include <stdlib.h>
2
11
“Try to imagine all life as you know it stopping instantaneously and every molecule in your body exploding at the speed of light.”
—Egon Spengler
Chapter 23. <stdlib.h> Standard Library Functions 264
3 int main(void)
4 {
5 // Allocate space for 5 ints
6 int *p = malloc(5 * sizeof(int));
7
8 p[0] = 12;
9 p[1] = 30;
10
See Also
malloc(), calloc(), aligned_alloc()
23.11 realloc()
Resize a previously allocated stretch of memory
Synopsis
#include <stdlib.h>
Description
This takes a pointer to some memory previously allocated with malloc() or calloc() and resizes it to the
new size.
If the new size is smaller than the old size, any data larger than the new size is discarded.
If the new size is larger than the old size, the new larger part is uninitialized. (You can clear it with memset().)
Important note: the memory might move! If you resize, the system might need to relocate the memory to a
larger continguous chunk. If this happens, realloc() will copy the old data to the new location for you.
Because of this, it’s important to save the returned value to your pointer to update it to the new location if
things move. (Also, be sure to error-check so that you don’t overwrite your old pointer with NULL, leaking
the memory.)
You can also relloc() memory allocated with aligned_alloc(), but it will potentially lose its alignment
if the block is moved.
Return Value
Returns a pointer to the resized memory region. This might be equivalent to the ptr passed in, or it might
be some other location.
Chapter 23. <stdlib.h> Standard Library Functions 265
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(void)
5 {
6 // Allocate space for 5 ints
7 int *p = malloc(5 * sizeof(int));
8
9 p[0] = 12;
10 p[1] = 30;
11
15 if (new_p == NULL) {
16 printf("Error reallocing\n");
17 } else {
18 p = new_p; // It's good; let's keep it
19 p[7] = 99;
20 }
21
22 // All done
23 free(p);
24 }
See Also
malloc(), calloc()
23.12 abort()
Abruptly end program execution
Synopsis
#include <stdlib.h>
Description
This ends program execution abnormally and immediately. Use this in rare, unexpected circumstances.
Open streams might not be flushed. Temporary files created might not be removed. Exit handlers are not
called.
A non-zero exit status is returned to the environment.
On some systems, abort() might dump core12 , but this is outside the scope of the spec.
12
https://en.wikipedia.org/wiki/Core_dump
Chapter 23. <stdlib.h> Standard Library Functions 266
You can cause the equivalent of an abort() by calling raise(SIGABRT), but I don’t know why you’d do
that.
The only portable way to stop an abort() call midway is to use signal() to catch SIGABRT and then
exit() in the signal handler.
Return Value
This function never returns.
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(void)
5 {
6 int bad_thing = 1;
7
8 if (bad_thing) {
9 printf("This should never have happened!\n");
10 fflush(stdout); // Make sure the message goes out
11 abort();
12 }
13 }
See Also
signal()
Synopsis
#include <stdlib.h>
Description
When the program does a normal exit with exit() or returns from main(), it looks for previously-registered
handlers to call on the way out. These handlers are registered with the atexit() call.
Chapter 23. <stdlib.h> Standard Library Functions 267
Think of it like, “Hey, when you’re about to exit, do these extra things.”
For the quick_exit() call, you can use the at_quick_exit() function to register handlers for that13 .
There’s no crossover in handlers from exit() to quick_exit(), i.e. for a call to one, none of the other’s
handlers will fire.
You can register multiple handlers to fire—at least 32 handlers are supported by both exit() and
quick_exit().
The argument func to the functions looks a little weird—it’s a pointer to a function to call. Basically just
put the function name to call in there (without parentheses after). See the example, below.
If you call atexit() from inside your atexit() handler (or equivalent in your at_quick_exit() handler),
it’s unspecified if it will get called. So get them all registered before you exit.
When exiting, the functions will be called in the reverse order they were registered.
Return Value
These functions return 0 on success, or nonzero on failure.
Example
atexit():
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 void exit_handler_1(void)
5 {
6 printf("Exit handler 1 called!\n");
7 }
8
9 void exit_handler_2(void)
10 {
11 printf("Exit handler 2 called!\n");
12 }
13
14 int main(void)
15 {
16 atexit(exit_handler_1);
17 atexit(exit_handler_2);
18
19 exit(0);
20 }
4 void exit_handler_1(void)
13
quick_exit() differs from exit() in that open files might not be flushed and temporary files might not be removed.
Chapter 23. <stdlib.h> Standard Library Functions 268
5 {
6 printf("Exit handler 1 called!\n");
7 }
8
9 void exit_handler_2(void)
10 {
11 printf("Exit handler 2 called!\n");
12 }
13
14 int main(void)
15 {
16 at_quick_exit(exit_handler_1);
17 at_quick_exit(exit_handler_2);
18
19 quick_exit(0);
20 }
See Also
exit(), quick_exit()
Synopsis
#include <stdlib.h>
Description
All these functions cause the program to exit, with various levels of cleanup performed.
exit() does the most cleanup and is the most normal exit.
Calling either of exit() or quick_exit() causes their respective atexit() or at_quick_exit() handlers
to be called in the reverse order in which they were registered.
exit() will flush all streams and delete all temporary files.
Status Description
EXIT_SUCCESS Typically returned when good things happen
0 Same as EXIT_SUCCESS
EXIT_FAILURE Oh noes! Definitely failure!
Any positive value Generally indicates another failure of some kind
Return Value
None of these functions ever return.
Example
1 #include <stdlib.h>
2
3 int main(void)
4 {
5 int contrived_exit_type = 1;
6
7 switch(contrived_exit_type) {
8 case 1:
9 exit(EXIT_SUCCESS);
10
11 case 2:
12 // Not supported in OS X
13 quick_exit(EXIT_SUCCESS);
14
15 case 3:
16 _Exit(2);
17 }
18 }
See Also
atexit(), at_quick_exit()
23.15 getenv()
Get the value of an environment variable
Synopsis
#include <stdlib.h>
Description
The environment often provides variables that are set before the program run that you can access at runtime.
Of course the exact details are system dependent, but these variables are key/value pairs, and you can get the
value by passing the key to getenv() as the name parameter.
You’re not allowed to overwrite the string that’s returned.
This is pretty limited in the standard, but your OS often provides better functionality.
Return Value
Returns a pointer to the environment variable value, or NULL if the variable doesn’t exist.
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(void)
5 {
6 printf("PATH is %s\n", getenv("PATH"));
7 }
23.16 system()
Run an external program
Synopsis
#include <stdlib.h>
Description
This will run an external program and then return to the caller.
The manner in which it runs the program is system-defined, but typically you can pass something to it just
like you’d run on the command line, searching the PATH, etc.
Not all systems have this capability, but you can test for it by passing NULL to system() and seeing if it
returns 0 (no command processor is available) or non-zero (a command processor is available! Yay!)
If you’re getting user input and passing it to the system() call, be extremely careful to escape all special shell
characters (everything that’s not alphanumeric) with a backslash to keep a villain from running something
you don’t want them to.
Chapter 23. <stdlib.h> Standard Library Functions 271
Return Value
If NULL is passed, returns nonzero if a command processor is available (i.e. system() will work at all).
Otherwise returns an implementation-defined value.
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(void)
5 {
6 printf("Here's a directory listing:\n\n");
7
10 printf("\nAll done!\n");
11 }
Output:
Here's a directory listing:
total 92
drwxr-xr-x 3 beej beej 4096 Oct 14 21:38 bin
drwxr-xr-x 2 beej beej 4096 Dec 20 20:07 examples
-rwxr-xr-x 1 beej beej 16656 Feb 23 21:49 foo
-rw-rw-rw- 1 beej beej 155 Feb 23 21:49 foo.c
-rw-r--r-- 1 beej beej 1350 Jan 27 22:11 Makefile
-rw-r--r-- 1 beej beej 4644 Jan 18 09:12 README.md
drwxr-xr-x 3 beej beej 4096 Feb 23 20:21 src
drwxr-xr-x 6 beej beej 4096 Feb 21 20:24 stage
drwxr-xr-x 2 beej beej 4096 Sep 27 20:54 translations
drwxr-xr-x 2 beej beej 4096 Sep 27 20:54 website
All done!
23.17 bsearch()
Binary Search (maybe) an array of objects
Synopsis
#include <stdlib.h>
Description
This crazy-looking function searches an array for a value.
Chapter 23. <stdlib.h> Standard Library Functions 272
It probably is a binary search or some fast, efficient search. But the spec doesn’t really say.
However, the array must be sorted! So binary search seems likely.
• key is a pointer to the value to find.
• base is a pointer to the start of the array—the array must be sorted!
• nmemb is the number of elements in the array.
• size is the sizeof each element in the array.
• compar is a pointer to a function that will compare the key against other values.
The comparison function takes the key as the first argument and the value to compare against as the second.
It should return a negative number if the key is less than the value, 0 if the key equals the value, and a positive
number if the key is greater than the value.
This is commonly computed by taking the difference between the key and the value to be compared. If
subtraction is supported.
The return value from the strcmp() function can be used for comparing strings.
Again, the array must be sorted according to the order of the comparison function before running bsearch().
Luckily for you, you can just call qsort() with the same comparison function to get this done.
It’s a general-purpose function—it’ll search any type of array for anything. The catch is you have to write
the comparison function.
And that’s not as scary as it looks. Jump down to the example
Return Value
The function returns a pointer to the found value, or NULL if it can’t be found.
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3
8 return *k - *v;
9 }
10
11 int main(void)
12 {
13 int a[9] = {2, 6, 9, 12, 13, 18, 20, 32, 47};
14
25
Output:
Found 12
Didn't find 30
Found 32
See Also
strcmp(), qsort()
23.18 qsort()
Quicksort (maybe) some data
Synopsis
#include <stdlib.h>
Description
This function will quicksort (or some other sort, probably speedy) an array of data in-place14 .
Like bsearch(), it’s data-agnostic. Any data for which you can define a relative ordering can be sorted,
whether ints, structs, or anything else.
Also like bsearch(), you have to give a comparison function to do the actual compare.
• base is a pointer to the start of the array to be sorted.
• nmemb is the number of elements in the array.
• size is the sizeof each element.
• compar is a pointer to the comparison function.
The comparison function takes pointers to two elements of the array as arguments and compares them. It
should return a negative number if the first argument is less than the second, 0 if they are equal, and a positive
number if the first argument is greater than the second.
This is commonly computed by taking the difference between the first argument and the second. If subtraction
is supported.
The return value from the strcmp() function can provide sort order for strings.
If you have to sort a struct, just subtract the specific field you want to sort by.
This comparison function can be used by bsearch() to do searches after the list is sorted.
To reverse the sort, subtract the second argument from the first, i.e. negate the return value from compar().
14
“In-place” meaning that the original array will hold the results; no new array is allocated.
Chapter 23. <stdlib.h> Standard Library Functions 274
Return Value
Returns nothing!
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3
13 int main(void)
14 {
15 int a[9] = {14, 2, 3, 17, 10, 8, 6, 1, 13};
16
26 putchar('\n');
27
Output:
1 2 3 6 8 10 13 14 17
Found 17!
See Also
strcmp(), bsearch()
Synopsis
#include <stdlib.h>
Description
Compute the absolute value of j. If you don’t remember, that’s how far from zero j is.
In other words, if j is negative, return it as a positive. If it’s positive, return it as a positive. Always be
positive. Enjoy life.
If the result cannot be represented, the behavior is undefined. Be especially aware of the upper half of
unsigned numbers.
Return Value
Returns the absolute value of j, |𝑗|.
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(void)
5 {
6 printf("|-2| = %d\n", abs(-2));
7 printf("|4| = %d\n", abs(4));
8 }
Output:
|-2| = 2
|4| = 4
See Also
fabs()
Synopsis
#include <stdlib.h>
Chapter 23. <stdlib.h> Standard Library Functions 276
Description
These functions get you the quotient and remainder of a pair of numbers in one go.
They return a structure that has two fields, quot, and rem, the types of which match types of numer and
denom. Note how each function returns a different variant of div_t.
typedef struct {
long int quot, rem;
} ldiv_t;
typedef struct {
long long int quot, rem;
} lldiv_t;
Return Value
A div_t, ldiv_t, or lldiv_t structure with the quot and rem fields loaded with the quotient and remainder
of the operation of numer/denom.
Chapter 23. <stdlib.h> Standard Library Functions 277
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(void)
5 {
6 div_t d = div(64, -7);
7
Output:
64 / -7 = -9
64 % -7 = 1
See Also
fmod(), remainder()
23.21 mblen()
Return the number of bytes in a multibyte character
Synopsis
#include <stdlib.h>
Description
If you have a multibyte character in a string, this will tell you how many bytes long it is.
n is the maximum number of bytes mblen() will scan before giving up.
If s is a NULL pointer, tests if this encoding has state dependency, as noted in the return value, below. It also
resets the state, if there is one.
The behavior of this function is influenced by the locale.
Return Value
Returns the number of bytes used to encode this character, or -1 if there is no valid multibyte character in
the next n bytes.
Or, if s is NULL, returns true if this encoding has state dependency.
Example
For the example, I used my extended character set to put Unicode characters in the source. If this doesn’t
work for you, use the \uXXXX escape.
Chapter 23. <stdlib.h> Standard Library Functions 278
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <locale.h>
4
5 int main(void)
6 {
7 setlocale(LC_ALL, "");
8
Output (in my case, the encoding is UTF-8, but your mileage may vary):
State dependency: 0
Bytes for €: 3
Bytes for é: 2
Bytes for &: 1
See Also
mbtowc(), mbstowcs()), setlocale()
23.22 mbtowc()
Convert a multibyte character to a wide character
Synopsis
#include <stdlib.h>
Description
If you have a multibyte character, this function will convert it to a wide character and stored at the address
pointed to by pwc. Up to n bytes of the multibyte character will be analyzed.
If pwc is NULL, the resulting character will not be stored. (Useful for just getting the return value.)
If s is a NULL pointer, tests if this encoding has state dependency, as noted in the return value, below. It also
resets the state, if there is one.
The behavior of this function is influenced by the locale.
Return Value
Returns the number of bytes used in the encoded wide character, or -1 if there is no valid multibyte character
in the next n bytes.
Returns 0 if s points to the NUL character.
Chapter 23. <stdlib.h> Standard Library Functions 279
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <locale.h>
4 #include <wchar.h>
5
6 int main(void)
7 {
8 setlocale(LC_ALL, "");
9
12 wchar_t wc;
13 int bytes;
14
Output on my system:
State dependency: 0
L'€' takes 3 bytes as multibyte char '€'
See Also
mblen(), mbstowcs(), wcstombs(), setlocale()
23.23 wctomb()
Convert a wide character to a multibyte character
Synopsis
#include <stdlib.h>
Description
If you have your hands on a wide character, you can use this to make it multibyte.
The wide character wc is stored as a multibyte character in the string pointed to by s. The buffer s points to
should be at least MB_CUR_MAX characters long. Note that MB_CUR_MAX changes with locale.
If wc is a NUL wide character, a NUL is stored in s after the bytes needed to reset the shift state (if any).
If s is a NULL pointer, tests if this encoding has state dependency, as noted in the return value, below. It also
resets the state, if there is one.
Chapter 23. <stdlib.h> Standard Library Functions 280
Return Value
Returns the number of bytes used in the encoded multibyte character, or -1 if wc does not correspond to any
valid multibyte character.
Or, if s is NULL, returns true if this encoding has state dependency.
Example
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <locale.h>
4 #include <wchar.h>
5
6 int main(void)
7 {
8 setlocale(LC_ALL, "");
9
12 int bytes;
13 char mb[MB_CUR_MAX + 1];
14
Output on my system:
State dependency: 0
L'€' takes 3 bytes as multibyte char '€'
See Also
mbtowc(), mbstowcs(), wcstombs(), setlocale()
23.24 mbstowcs()
Convert a multibyte string to a wide character string
Synopsis
#include <stdlib.h>
Description
If you have a multibyte string (AKA a regular string), you can convert it wto a wide character string with
this function.
At most n wide characters are written to the destination pwcs from the source s.
A NUL character is stored as a wide NUL character.
Non-portable POSIX extension: if you’re using a POSIX-complaint library, this function allows pwcs to be
NULL if you’re only interested in the return value. Most notably, this will give you the number of characters
in a multibyte string (as opposed to strlen() which counts the bytes.)
Return Value
Returns the number of wide characters written to the destination pwcs.
If an invalid multibyte character was found, returns (size_t)(-1).
If the return value is n, it means the result was not NUL-terminated.
Example
This source uses an extended character set. If your compiler doesn’t support it, you’ll have to replace them
with \u escapes.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <locale.h>
4 #include <string.h>
5
6 int main(void)
7 {
8 setlocale(LC_ALL, "");
9
10 wchar_t wcs[128];
11 char *s = "€200 for this spoon?"; // 20 characters
12
27 s = "§¶°±π€•"; // 7 characters
28
See Also
mblen(), mbtowc(), wcstombs(), setlocale()
23.25 wcstombs()
Convert a wide character string to a multibyte string
Synopsis
#include <stdlib.h>
Description
If you have a wide character string and you want it as multibyte string, this is the function for you!
It’ll take the wide characters pointed to by pwcs and convert them to multibyte characters stored in s. No
more than n bytes will be written to s.
Non-portable POSIX extension: if you’re using a POSIX-complaint library, this function allows s to be NULL
if you’re only interested in the return value. Most notably, this will give you the number of bytes needed to
encode the wide characters in a multibyte string.
Return Value
Returns the number of bytes written to s, or (size_t)(-1) if one of the characters can’t be encoded into a
multibyte string.
If the return value is n, it means the result was not NUL-terminated.
Example
This source uses an extended character set. If your compiler doesn’t support it, you’ll have to replace them
with \u escapes.
Chapter 23. <stdlib.h> Standard Library Functions 283
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <locale.h>
4 #include <string.h>
5
6 int main(void)
7 {
8 setlocale(LC_ALL, "");
9
10 char mbs[128];
11 wchar_t *wcs = L"€200 for this spoon?"; // 20 characters
12
13 size_t byte_count;
14
See Also
mblen(), wctomb(), mbstowcs(), setlocale()
Chapter 24
This header provides a macro noreturn that is a handy alias for _Noreturn.
Use this macro to indicate to the compiler that a function will never return to the caller. It’s undefined
behavior if the so-marked function does return.
Here’s a usage example:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdnoreturn.h>
4
12 int main(void)
13 {
14 foo();
15 }
284
Chapter 25
Function Description
memchr() Find the first occurrence of a character in memory.
memcmp() Compare two regions of memory.
memcpy() Copy a region of memory to another.
memmove() Move a (potentially overlapping) region of memory.
memset() Set a region of memory to a value.
strcat() Concatenate (join) two strings together.
strchr() Find the first occurrence of a character in a string.
strcmp() Compare two strings.
strcoll() Compare two strings accounting for locale.
strcpy() Copy a string.
strcspn() Find length of a string not consisting of a set of
characters.
strerror() Return a human-readable error message for a given
code.
strlen() Return the length of a string.
strncat() Concatenate (join) two strings, length-limited.
strncmp() Compare two strings, length-limited.
strncpy() Copy two strings, length-limited.
strpbrk() Search a string for one of a set of character.
strrchr() Find the last occurrence of a character in a string.
strspn() Find length of a string consisting of a set of
characters.
strstr() Find a substring in a string.
strtok() Tokenize a string.
strxfrm() Prepare a string for comparison as if by strcoll().
As has been mentioned earlier in the guide, a string in C is a sequence of bytes in memory, terminated by a
NUL character (‘\0’). The NUL at the end is important, since it lets all these string functions (and printf()
and puts() and everything else that deals with a string) know where the end of the string actually is.
Fortunately, when you operate on a string using one of these many functions available to you, they add the
NUL terminator on for you, so you actually rarely have to keep track of it yourself. (Sometimes you do,
especially if you’re building a string from scratch a character at a time or something.)
In this section you’ll find functions for pulling substrings out of strings, concatenating strings together, getting
the length of a string, and so forth and so on.
285
Chapter 25. <string.h> String Manipulation 286
Synopsis
#include <string.h>
void *memcpy(void * restrict s1, const void * restrict s2, size_t n);
Description
These functions copy memory—as many bytes as you want! From source to destination!
The main difference between the two is that memcpy() cannot safely copy overlapping memory regions,
whereas memmove() can.
On the one hand, I’m not sure why you’d want to ever use memcpy() instead of memmove(), but I’ll bet it’s
possibly more performant.
The parameters are in a particular order: destination first, then source. I remember this order because it
behaves like an “=” assignment: the destination is on the left.
Return Value
Both functions return whatever you passed in for parameter s1 for your convenience.
Example
1 #include <string.h>
2
3 int main(void)
4 {
5 char s[100] = "Goats";
6 char t[100];
7
See Also
strcpy(), strncpy()
Synopsis
#include <string.h>
Description
These functions copy a string from one address to another, stopping at the NUL terminator on the srcstring.
strncpy() is just like strcpy(), except only the first n characters are actually copied. Beware that if you
hit the limit, n before you get a NUL terminator on the src string, your dest string won’t be NUL-terminated.
Beware! BEWARE!
(If the src string has fewer than n characters, it works just like strcpy().)
You can terminate the string yourself by sticking the '\0' in there yourself:
char s[10];
char foo = "My hovercraft is full of eels."; // more than 10 chars
Return Value
Both functions return dest for your convenience, at no extra charge.
Example
1 #include <string.h>
2
3 int main(void)
4 {
5 char *src = "hockey hockey hockey hockey hockey hockey hockey hockey";
6 char dest[20];
7
8 int len;
9
12 len = strlen(dest);
13
14 // tricky, but let's use some pointer arithmetic and math to append
15 // as much of src as possible onto the end of dest, -1 on the length to
16 // leave room for the terminator:
17 strncpy(dest+len, src, sizeof(dest)-len-1);
18
See Also
memcpy(), strcat(), strncat()
Synopsis
#include <string.h>
Description
“Concatenate”, for those not in the know, means to “stick together”. These functions take two strings, and
stick them together, storing the result in the first string.
These functions don’t take the size of the first string into account when it does the concatenation. What this
means in practical terms is that you can try to stick a 2 megabyte string into a 10 byte space. This will lead
to unintended consequences, unless you intended to lead to unintended consequences, in which case it will
lead to intended unintended consequences.
Technical banter aside, your boss and/or professor will be irate.
If you want to make sure you don’t overrun the first string, be sure to check the lengths of the strings first
and use some highly technical subtraction to make sure things fit.
You can actually only concatenate the first n characters of the second string by using strncat() and speci-
fying the maximum number of characters to copy.
Return Value
Both functions return a pointer to the destination string, like most of the string-oriented functions.
Example
1 #include <stdio.h>
2 #include <string.h>
3
4 int main(void)
5 {
6 char dest[30] = "Hello";
7 char *src = ", World!";
8 char numbers[] = "12345678";
Chapter 25. <string.h> String Manipulation 289
12 strcat(dest, src);
13 printf("dest after strcat: \"%s\"\n", dest); // "Hello, world!"
14
Notice I mixed and matched pointer and array notation there with src and numbers; this is just fine with
string functions.
See Also
strlen()
Synopsis
#include <string.h>
Description
All these functions compare chunks of bytes in memory.
strcmp() and strncmp() operate on NUL-terminated strings, whereas memcmp() will compare the number
of bytes you specify, brazenly ignoring any NUL characters it finds along the way.
strcmp() compares the entire string down to the end, while strncmp() only compares the first n characters
of the strings.
It’s a little funky what they return. Basically it’s a difference of the strings, so if the strings are the same,
it’ll return zero (since the difference is zero). It’ll return non-zero if the strings differ; basically it will find
the first mismatched character and return less-than zero if that character in s1 is less than the corresponding
character in s2. It’ll return greater-than zero if that character in s1 is greater than that in s2.
So if they return 0, the comparison was equal (i.e. the difference was 0.)
These functions can be used as comparison functions for qsort() if you have an array of char*s you want
to sort.
Chapter 25. <string.h> String Manipulation 290
Return Value
Returns zero if the strings or memory are the same, less-than zero if the first different character in s1 is less
than that in s2, or greater-than zero if the first difference character in s1 is greater than than in s2.
Example
1 #include <stdio.h>
2 #include <string.h>
3
4 int main(void)
5 {
6 char *s1 = "Muffin";
7 char *s2 = "Muffin Sandwich";
8 char *s3 = "Muffin";
9
16 if (strcmp(s1, s2) == 0)
17 printf("This won't get printed because the strings differ\n");
18
19 if (strcmp(s1, s3) == 0)
20 printf("This will print because s1 and s3 are the same\n");
21
28 if (!strcmp(s1, s3))
29 printf("The strings are the same!\n");
30
See Also
memcmp(), qsort()
25.5 strcoll()
Compare two strings accounting for locale
Chapter 25. <string.h> String Manipulation 291
Synopsis
#include <string.h>
Description
This is basically strcmp(), except that it handles accented characters better depending on the locale.
For example, my strcmp() reports that the character “é” (with accent) is greater than “f”. But that’s hardly
useful for alphabetizing.
By setting the LC_COLLATE locale value (either by name or via LC_ALL), you can have strcoll() sort in a
way that’s more meaningful by the current locale. For example, by having “é” appear sanely before “f”.
It’s also a lot slower than strcmp() so use it only if you have to. See strxfrm() for a potential speedup.
Return Value
Like the other string comparison functions, strcoll() returns a negative value if s1 is less than s2, or a
positive value if s1 is greater than s2. Or 0 if they are equal.
Example
1 #include <stdio.h>
2 #include <string.h>
3 #include <locale.h>
4
5 int main(void)
6 {
7 setlocale(LC_ALL, "");
8
See Also
strcmp()
25.6 strxfrm()
Transform a string for comparing based on locale
Synopsis
Chapter 25. <string.h> String Manipulation 292
#include <string.h>
size_t strxfrm(char * restrict s1, const char * restrict s2, size_t n);
Description
This is a strange little function, so bear with me.
Firstly, if you haven’t done so, get familiar with strcoll() because this is closely related to that.
OK! Now that you’re back, you can think of strxfrm() as the first part of the strcoll() internals. Basi-
cally, strcoll() has to transform a string into a form that can be compared with strcmp(). And it does
this with strxfrm() for both strings every time you call it.
strxform() takes string s2 and transforms it (readies it for strcmp()) storing the result in s1. It writes no
more than n bytes, protecting us from terrible buffer overflows.
But hang on—there’s another mode! If you pass NULL for s1 and 0 for n, it will return the number of bytes
that the transformed string would have used1 . This is useful if you need to allocate some space to hold the
transformed string before you strcmp() it against another.
What I’m getting at, not to be too blunt, is that strcoll() is slow compared to strcmp(). It does a lot of
extra work running strxfrm() on all its strings.
In fact, we can see how it works by writing our own like this:
1 int my_strcoll(char *s1, char *s2)
2 {
3 // Use n = 0 to just get the lengths of the transformed strings
4 int len1 = strxfrm(NULL, s1, 0) + 1;
5 int len2 = strxfrm(NULL, s2, 0) + 1;
6
22 return result;
23 }
You see on lines 12, 13, and 16, above how we transform the two input strings and then call strcmp() on
the result.
So why do we have this function? Can’t we just call strcoll() and be done with it?
1
It always returns the number of bytes the transformed string took, but in this case because s1 was NULL, it doesn’t actually write a
transformed string.
Chapter 25. <string.h> String Manipulation 293
The idea is that if you have one string that you’re going to be comparing against a whole lot of other ones,
maybe you just want to transform that string one time, then use the faster strcmp() saving yourself a bunch
of the work we had to do in the function, above.
We’ll do that in the example.
Return Value
Returns the number of bytes in the transformed sequence. If the value is greater than n, the results in s1 are
meaningless.
Example
1 #include <stdio.h>
2 #include <string.h>
3 #include <locale.h>
4 #include <stdlib.h>
5
13 strxfrm(d, s, len);
14
15 return d;
16 }
17
26 free(s1_transformed);
27
28 return result;
29 }
30
31 int main(void)
32 {
33 setlocale(LC_ALL, "");
34
42
43 free(s);
44 }
See Also
strcoll()
Synopsis
#include <string.h>
Description
The functions strchr() and strrchr find the first or last occurrence of a letter in a string, respectively. (The
extra “r” in strrchr() stands for “reverse”–it looks starting at the end of the string and working backward.)
Each function returns a pointer to the char in question, or NULL if the letter isn’t found in the string.
memchr() is similar, except that instead of stopping on the first NUL character, it continues searching for
however many bytes you specify.
Quite straightforward.
One thing you can do if you want to find the next occurrence of the letter after finding the first, is call the
function again with the previous return value plus one. (Remember pointer arithmetic?) Or minus one if
you’re looking in reverse. Don’t accidentally go off the end of the string!
Return Value
Returns a pointer to the occurrence of the letter in the string, or NULL if the letter is not found.
Example
1 #include <stdio.h>
2 #include <string.h>
3
4 int main(void)
5 {
6 // "Hello, world!"
7 // ^ ^ ^
8 // A B C
9
Chapter 25. <string.h> String Manipulation 295
Output:
Found a 'B' here: BIG BROWN BAT BIT BEEJ
Found a 'B' here: BROWN BAT BIT BEEJ
Found a 'B' here: BAT BIT BEEJ
Found a 'B' here: BIT BEEJ
Found a 'B' here: BEEJ
Synopsis
#include <string.h>
Description
strspn() will tell you the length of a string consisting entirely of the set of characters in accept. That is,
it starts walking down str until it finds a character that is not in the set (that is, a character that is not to be
accepted), and returns the length of the string so far.
strcspn() works much the same way, except that it walks down str until it finds a character in the reject
set (that is, a character that is to be rejected.) It then returns the length of the string so far.
Return Value
The length of the string consisting of all characters in accept (for strspn()), or the length of the string
consisting of all characters except reject (for strcspn()).
Chapter 25. <string.h> String Manipulation 296
Example
1 #include <stdio.h>
2 #include <string.h>
3
4 int main(void)
5 {
6 char str1[] = "a banana";
7 char str2[] = "the bolivian navy on maenuvers in the south pacific";
8 int n;
9
10 // how many letters in str1 until we reach something that's not a vowel?
11 n = strspn(str1, "aeiou");
12 printf("%d\n", n); // n == 1, just "a"
13
See Also
strchr(), strrchr()
25.9 strpbrk()
Search a string for one of a set of characters
Synopsis
#include <string.h>
Description
This function searches string s1 for any of the characters that are found in string s2.
It’s just like how strchr() searches for a specific character in a string, except it will match any of the
characters found in s2.
Think of the power!
Return Value
Returns a pointer to the first character matched in s1, or NULL if the string isn’t found.
Chapter 25. <string.h> String Manipulation 297
Example
1 #include <stdio.h>
2 #include <string.h>
3
4 int main(void)
5 {
6 // p points here after strpbrk
7 // v
8 char *s1 = "Hello, world!";
9 char *s2 = "dow!"; // Match any of these chars
10
See Also
strchr(), memchr()
25.10 strstr()
Find a string in another string
Synopsis
#include <string.h>
Description
Let’s say you have a big long string, and you want to find a word, or whatever substring strikes your fancy,
inside the first string. Then strstr() is for you! It’ll return a pointer to the substr within the str!
Return Value
You get back a pointer to the occurrence of the substr inside the str, or NULL if the substring can’t be found.
Example
1 #include <stdio.h>
2 #include <string.h>
3
4 int main(void)
5 {
6 char *str = "The quick brown fox jumped over the lazy dogs.";
7 char *p;
8
Chapter 25. <string.h> String Manipulation 298
9 p = strstr(str, "lazy");
10 printf("%s\n", p == NULL? "null": p); // "lazy dogs."
11
See Also
strchr(), strrchr(), strspn(), strcspn()
25.11 strtok()
Tokenize a string
Synopsis
#include <string.h>
Description
If you have a string that has a bunch of separators in it, and you want to break that string up into individual
pieces, this function can do it for you.
The usage is a little bit weird, but at least whenever you see the function in the wild, it’s consistently weird.
Basically, the first time you call it, you pass the string, str that you want to break up in as the first argument.
For each subsequent call to get more tokens out of the string, you pass NULL. This is a little weird, but
strtok() remembers the string you originally passed in, and continues to strip tokens off for you.
Note that it does this by actually putting a NUL terminator after the token, and then returning a pointer to
the start of the token. So the original string you pass in is destroyed, as it were. If you need to preserve the
string, be sure to pass a copy of it to strtok() so the original isn’t destroyed.
Return Value
A pointer to the next token. If you’re out of tokens, NULL is returned.
Example
1 #include <stdio.h>
2 #include <string.h>
3
4 int main(void)
5 {
6 // break up the string into a series of space or
7 // punctuation-separated words
8 char str[] = "Where is my bacon, dude?";
Chapter 25. <string.h> String Manipulation 299
9 char *token;
10
Output:
Word: "Where"
Word: "is"
Word: "my"
Word: "bacon"
Word: "dude"
See Also
strchr(), strrchr(), strspn(), strcspn()
25.12 memset()
Set a region of memory to a certain value
Synopsis
#include <string.h>
Description
This function is what you use to set a region of memory to a particular value, namely c converted into
unsigned char.
Return Value
memset() returns whatever you passed in as s for happy convenience.
Chapter 25. <string.h> String Manipulation 300
Example
1 #include <stdio.h>
2 #include <string.h>
3
4 int main(void)
5 {
6 struct banana {
7 float ripeness;
8 char *peel_color;
9 int grams;
10 };
11
12 struct banana b;
13
See Also
memcpy(), memmove()
25.13 strerror()
Get a string version of an error number
Synopsis
#include <string.h>
Description
This function ties closely into perror() (which prints a human-readable error message corresponding to
errno). But instead of printing, strerror() returns a pointer to the locale-specific error message string.
So if you ever need that string back for some reason (e.g. you’re going to fprintf() it to a file or something),
this function will give it to you. All you need to do is pass in errno as an argument. (Recall that errno gets
set as an error status by a variety of functions.)
You can actually pass in any integer for errnum you want. The function will return some message, even if
the number doesn’t correspond to any known value for errno.
The values of errno and the strings returned by strerror() are system-dependent.
Return Value
A string error message corresponding to the given error number.
Chapter 25. <string.h> String Manipulation 301
Example
1 #include <stdio.h>
2 #include <string.h>
3 #include <errno.h>
4
5 int main(void)
6 {
7 FILE *fp = fopen("NONEXISTENT_FILE.TXT", "r");
8
9 if (fp == NULL) {
10 char *errmsg = strerror(errno);
11 printf("Error %d opening file: %s\n", errno, errmsg);
12 }
13 }
Output:
Error 2 opening file: No such file or directory
See Also
perror()
25.14 strlen()
Returns the length of a string
Synopsis
#include <string.h>
Description
This function returns the length of the passed null-terminated string (not counting the NUL character at
the end). It does this by walking down the string and counting the bytes until the NUL character, so it’s a
little time consuming. If you have to get the length of the same string repeatedly, save it off in a variable
somewhere.
Return Value
Returns the number of bytes in the string. Note that this might be different than the number of characters in
a multibyte string.
Example
Chapter 25. <string.h> String Manipulation 302
1 #include <stdio.h>
2 #include <string.h>
3
4 int main(void)
5 {
6 char *s = "Hello, world!"; // 13 characters
7
See Also
Chapter 26
These are type-generic macros that are wrappers around the math functions in <math.h> and <complex.h>.
This header includes both of those.
But on the surface, you can think of them as being able to use, say, the sqrt() function with any type without
needed to think about if it’s double or long double or even complex.
These are the defined macros—some of them don’t have a counterpart in the real or complex space. Type
suffixes are omitted in the table on the Real and Complex columns. None of the generic macros have type
suffixes.
303
Chapter 26. <tgmath.h> Type-Generic Math Functions 304
26.1 Example
Here’s an example where we call the type-generic sqrt() function on a variety of types.
1 #include <stdio.h>
2 #include <tgmath.h>
3
4 int main(void)
5 {
6 double x = 12.8;
7 long double y = 34.9;
8 double complex z = 1 + 2 * I;
9
10 double x_result;
11 long double y_result;
12 double complex z_result;
Chapter 26. <tgmath.h> Type-Generic Math Functions 305
13
Output:
x_result: 3.577709
y_result: 5.907622
z_result: 1.272020 + 0.786151i
Chapter 27
Function Description
call_once() Call a function one time no matter how many
threads try
cnd_broadcast() Wake up all threads waiting on a condition variable
cnd_destroy() Free up resources from a condition variable
cnd_init() Initialize a condition variable to make it ready for
use
cnd_signal() Wake up a thread waiting on a condition variable
cnd_timedwait() Wait on a condition variable with a timeout
cnd_wait() Wait for a signal on a condition variable
mtx_destroy() Cleanup a mutex when done with it
mtx_init() Initialize a mutex for use
mtx_lock() Acquire a lock on a mutex
mtx_timedlock() Lock a mutex allowing for timeout
mtx_trylock() Try to lock a mutex, returning if not possible
mtx_unlock() Free a mutex when you’re done with the critical
section
thrd_create() Create a new thread of execution
thrd_current() Get the ID of the calling thread
thrd_detach() Automatically clean up threads when they exit
thrd_equal() Compare two thread descriptors for equality
thrd_exit() Stop and exit this thread
thrd_join() Wait for a thread to exit
thrd_yield() Stop running that other threads might run
tss_create() Create new thread-specific storage
tss_delete() Clean up a thread-specific storage variable
tss_get() Get thread-specific data
tss_set() Set thread-specific data
306
Chapter 27. <threads.h> Multithreading Functions 307
Enjoy!
27.1 call_once()
Call a function one time no matter how many threads try
Synopsis
#include <threads.h>
Description
If you have a bunch of threads running over the same piece of code that calls a function, but you only want
that function to run one time, call_once() can help you out.
The catch is the function that is called doesn’t return anything and takes no arguments.
If you need more than that, you’ll have to set a threadsafe flag such as atomic_flag, or one that you protect
with a mutex.
To use this, you need to pass it a pointer to a function to execute, func, and also a pointer to a flag of type
once_flag.
once_flag is an opaque type, so all you need to know is that you initialize it to the value ONCE_FLAG_INIT.
Return Value
Returns nothing.
Example
1 #include <stdio.h>
2 #include <threads.h>
3
6 void run_once_function(void)
7 {
8 printf("I'll only run once!\n");
9 }
10
15 printf("Thread running!\n");
16
17 call_once(&of, run_once_function);
18
19 return 0;
20 }
Chapter 27. <threads.h> Multithreading Functions 308
21
22 #define THREAD_COUNT 5
23
24 int main(void)
25 {
26 thrd_t t[THREAD_COUNT];
27
27.2 cnd_broadcast()
Wake up all threads waiting on a condition variable
Synopsis
#include <threads.h>
Description
This is just like cnd_signal() in that it wakes up threads that are waiting on a condition variable…. except
instead of just rousing one thread, it wakes them all.
Of course, only one will get the mutex, and the rest will have to wait their turn. But instead of being asleep
waiting for a signal, they’ll be asleep waiting to reacquire the mutex. They’re rearin’ to go, in other words.
This can make a difference in a specific set of circumstances where cnd_signal() might leave you hanging.
If you’re relying on subsequent threads to issue the next cnd_signal(), but you have the cnd_wait() in
a while loop1 that doesn’t allow any threads to escape, you’ll be stuck. No more threads will be woken up
from the wait.
But if you cnd_broadcast(), all the threads will be woken, and presumably at least one of them will be
allowed to escape the while loop, freeing it up to broadcast the next wakeup when its work is done.
1
Which you should because of spurious wakeups.
Chapter 27. <threads.h> Multithreading Functions 309
Return Value
Returns thrd_success or thrd_error depending on how well things went.
Example
In the example below, we launch a bunch of threads, but they’re only allowed to run if their ID matches the
current ID. If it doesn’t, they go back to waiting.
If you cnd_signal() to wake the next thread, it might not be the one with the proper ID to run. If it’s not,
it goes back to sleep and we hang (because no thread is awake to hit cnd_signal() again).
But if you cnd_broadcast() to wake them all, then they’ll all try (one after another) to get out of the while
loop. And one of them will make it.
Try switching the cnd_broadcast() to cnd_signal() to see likely deadlocks. It doesn’t happen every
time, but usually does.
1 #include <stdio.h>
2 #include <threads.h>
3
4 cnd_t condvar;
5 mtx_t mutex;
6
13 mtx_lock(&mutex);
14
19 if (id != current_id)
20 printf("THREAD %d: woke up, but it's not my turn!\n", id);
21 else
22 printf("THREAD %d: woke up, my turn! Let's go!\n", id);
23 }
24
25 current_id++;
26
29 //cnd_signal(&condvar);
30 cnd_broadcast(&condvar);
31 mtx_unlock(&mutex);
32
33 return 0;
34 }
35
36 #define THREAD_COUNT 5
37
38 int main(void)
Chapter 27. <threads.h> Multithreading Functions 310
39 {
40 thrd_t t[THREAD_COUNT];
41 int id[] = {4, 3, 2, 1, 0};
42
43 mtx_init(&mutex, mtx_plain);
44 cnd_init(&condvar);
45
52 mtx_destroy(&mutex);
53 cnd_destroy(&condvar);
54 }
See how THREAD 0 signaled that it was THREAD 1’s turn? But—bad news—it was THREAD 4 that got woken
up. So no one continued the process. cnd_broadcast() would have woken them all, so eventually THREAD
1 would have run, gotten out of the while, and broadcast for the next thread to run.
See Also
cnd_signal(), mtx_lock(), mtx_unlock()
27.3 cnd_destroy()
Free up resources from a condition variable
Synopsis
#include <threads.h>
Description
This is the opposite of cnd_init() and should be called when all threads are done using a condition variable.
Return Value
Returns nothing!
Example
General-purpose condition variable example here, but you can see the cnd_destroy() down at the end.
1 #include <stdio.h>
2 #include <threads.h>
3
4 cnd_t condvar;
5 mtx_t mutex;
6
11 mtx_lock(&mutex);
12
13 printf("Thread: waiting...\n");
14 cnd_wait(&condvar, &mutex);
15 printf("Thread: running again!\n");
16
17 mtx_unlock(&mutex);
18
19 return 0;
Chapter 27. <threads.h> Multithreading Functions 312
20 }
21
22 int main(void)
23 {
24 thrd_t t;
25
26 mtx_init(&mutex, mtx_plain);
27 cnd_init(&condvar);
28
35 mtx_lock(&mutex);
36 printf("Main: signaling thread\n");
37 cnd_signal(&condvar);
38 mtx_unlock(&mutex);
39
40 thrd_join(t, NULL);
41
42 mtx_destroy(&mutex);
43 cnd_destroy(&condvar); // <-- DESTROY CONDITION VARIABLE
44 }
Output:
Main creating thread
Thread: waiting...
Main: signaling thread
Thread: running again!
See Also
cnd_init()
27.4 cnd_init()
Initialize a condition variable to make it ready for use
Synopsis
#include <threads.h>
Description
This is the opposite of cnd_destroy(). This prepares a condition variable for use, doing behind-the-scenes
work on it.
Chapter 27. <threads.h> Multithreading Functions 313
Return Value
If all goes well, returns thrd_success. It all doesn’t go well, it could return thrd_nomem if the system is
out of memory, or thread_error in the case of any other error.
Example
General-purpose condition variable example here, but you can see the cnd_init() down at the start of
main().
1 #include <stdio.h>
2 #include <threads.h>
3
4 cnd_t condvar;
5 mtx_t mutex;
6
11 mtx_lock(&mutex);
12
13 printf("Thread: waiting...\n");
14 cnd_wait(&condvar, &mutex);
15 printf("Thread: running again!\n");
16
17 mtx_unlock(&mutex);
18
19 return 0;
20 }
21
22 int main(void)
23 {
24 thrd_t t;
25
26 mtx_init(&mutex, mtx_plain);
27 cnd_init(&condvar); // <-- INITIALIZE CONDITION VARIABLE
28
35 mtx_lock(&mutex);
36 printf("Main: signaling thread\n");
37 cnd_signal(&condvar);
38 mtx_unlock(&mutex);
39
40 thrd_join(t, NULL);
41
42 mtx_destroy(&mutex);
Chapter 27. <threads.h> Multithreading Functions 314
43 cnd_destroy(&condvar);
44 }
Output:
Main creating thread
Thread: waiting...
Main: signaling thread
Thread: running again!
See Also
cnd_destroy()
27.5 cnd_signal()
Wake up a thread waiting on a condition variable
Synopsis
#include <threads.h>
Description
If you have a thread (or a bunch of threads) waiting on a condition variable, this function will wake one of
them up to run.
Compare to cnd_broadcast() that wakes up all the threads. See the cnd_broadcast() page for more
information on when you’re want to use that versus this.
Return Value
Returns thrd_success or thrd_error depending on how happy your program is.
Example
General-purpose condition variable example here, but you can see the cnd_signal() in the middle of
main().
1 #include <stdio.h>
2 #include <threads.h>
3
4 cnd_t condvar;
5 mtx_t mutex;
6
11 mtx_lock(&mutex);
Chapter 27. <threads.h> Multithreading Functions 315
12
13 printf("Thread: waiting...\n");
14 cnd_wait(&condvar, &mutex);
15 printf("Thread: running again!\n");
16
17 mtx_unlock(&mutex);
18
19 return 0;
20 }
21
22 int main(void)
23 {
24 thrd_t t;
25
26 mtx_init(&mutex, mtx_plain);
27 cnd_init(&condvar);
28
35 mtx_lock(&mutex);
36 printf("Main: signaling thread\n");
37 cnd_signal(&condvar); // <-- SIGNAL CHILD THREAD HERE!
38 mtx_unlock(&mutex);
39
40 thrd_join(t, NULL);
41
42 mtx_destroy(&mutex);
43 cnd_destroy(&condvar);
44 }
Output:
Main creating thread
Thread: waiting...
Main: signaling thread
Thread: running again!
See Also
cnd_init(), cnd_destroy()
27.6 cnd_timedwait()
Wait on a condition variable with a timeout
Chapter 27. <threads.h> Multithreading Functions 316
Synopsis
#include <threads.h>
Description
This is like cnd_wait() except we get to specify a timeout, as well.
Note that the thread still must reacquire the mutex to get more work done even after the timeout. The
the main difference is that regular cnd_wait() will only try to get the mutex after a cnd_signal() or
cnd_broadcast(), whereas cnd_timedwait() will do that, too, and try to get the mutex after the timeout.
The timeout is specified as an absolute UTC time since Epoch. You can get this with the timespec_get()
function and then add values on to the result to timeout later than now, as shown in the example.
Beware that you can’t have more than 999999999 nanoseconds in the tv_nsec field of the struct time-
spec. Mod those so they stay in range.
Return Value
If the thread wakes up for a non-timeout reason (e.g. signal or broadcast), returns thrd_success. If woken
up due to timeout, returns thrd_timedout. Otherwise returns thrd_error.
Example
This example has a thread wait on a condition variable for a maximum of 1.75 seconds. And it always times
out because no one ever sends a signal. Tragic.
1 #include <stdio.h>
2 #include <time.h>
3 #include <threads.h>
4
5 cnd_t condvar;
6 mtx_t mutex;
7
12 mtx_lock(&mutex);
13
26
27 printf("Thread: waiting...\n");
28 int r = cnd_timedwait(&condvar, &mutex, &ts);
29
30 switch (r) {
31 case thrd_success:
32 printf("Thread: signaled!\n");
33 break;
34
35 case thrd_timedout:
36 printf("Thread: timed out!\n");
37 return 1;
38
39 case thrd_error:
40 printf("Thread: Some kind of error\n");
41 return 2;
42 }
43
44 mtx_unlock(&mutex);
45
46 return 0;
47 }
48
49 int main(void)
50 {
51 thrd_t t;
52
53 mtx_init(&mutex, mtx_plain);
54 cnd_init(&condvar);
55
62 thrd_join(t, NULL);
63
64 mtx_destroy(&mutex);
65 cnd_destroy(&condvar);
66 }
Output:
Main creating thread
Thread: waiting...
Thread: timed out!
See Also
cnd_wait(), timespec_get()
Chapter 27. <threads.h> Multithreading Functions 318
27.7 cnd_wait()
Wait for a signal on a condition variable
Synopsis
#include <threads.h>
Description
This puts the calling thread to sleep until it is awakened by a call to cnd_signal() or cnd_broadcast().
Return Value
If everything’s fantastic, returns thrd_success. Otherwise it returns thrd_error to report that something
has gone fantastically, horribly awry.
Example
General-purpose condition variable example here, but you can see the cnd_wait() in the run() function.
1 #include <stdio.h>
2 #include <threads.h>
3
4 cnd_t condvar;
5 mtx_t mutex;
6
11 mtx_lock(&mutex);
12
13 printf("Thread: waiting...\n");
14 cnd_wait(&condvar, &mutex); // <-- WAIT HERE!
15 printf("Thread: running again!\n");
16
17 mtx_unlock(&mutex);
18
19 return 0;
20 }
21
22 int main(void)
23 {
24 thrd_t t;
25
26 mtx_init(&mutex, mtx_plain);
27 cnd_init(&condvar);
28
35 mtx_lock(&mutex);
36 printf("Main: signaling thread\n");
37 cnd_signal(&condvar); // <-- SIGNAL CHILD THREAD HERE!
38 mtx_unlock(&mutex);
39
40 thrd_join(t, NULL);
41
42 mtx_destroy(&mutex);
43 cnd_destroy(&condvar);
44 }
Output:
Main creating thread
Thread: waiting...
Main: signaling thread
Thread: running again!
See Also
cnd_timedwait()
27.8 mtx_destroy()
Cleanup a mutex when done with it
Synopsis
#include <threads.h>
Description
The opposite of mtx_init(), this function frees up any resources associated with the given mutex.
You should call this when all threads are done using the mutex.
Return Value
Returns nothing, the selfish ingrate!
Example
General-purpose mutex example here, but you can see the mtx_destroy() down at the end.
1 #include <stdio.h>
2 #include <threads.h>
3
Chapter 27. <threads.h> Multithreading Functions 320
4 cnd_t condvar;
5 mtx_t mutex;
6
13 mtx_lock(&mutex);
14
18 mtx_unlock(&mutex);
19
20 return 0;
21 }
22
23 #define THREAD_COUNT 5
24
25 int main(void)
26 {
27 thrd_t t[THREAD_COUNT];
28
29 mtx_init(&mutex, mtx_plain);
30
Output:
Thread: I got 0!
Thread: I got 1!
Thread: I got 2!
Thread: I got 3!
Thread: I got 4!
See Also
mtx_init()
27.9 mtx_init()
Initialize a mutex for use
Chapter 27. <threads.h> Multithreading Functions 321
Synopsis
#include <threads.h>
Description
Before you can use a mutex variable, you have to initialize it with this call to get it all prepped and ready to
go.
But wait! It’s not quite that simple. You have to tell it what type of mutex you want to create.
Type Description
mtx_plain Regular ol’ mutex
mtx_timed Mutex that supports timeouts
mtx_plain|mtx_recursive Recursive mutex
mtx_timed|mtx_recursive Recursive mutex that supports timeouts
As you can see, you can make a plain or timed mutex recursive by bitwise-ORing the value with
mtx_recursive.
“Recursive” means that the holder of a lock can call mtx_lock() multiple times on the same lock. (They
have to unlock it an equal number of times before anyone else can take the mutex.) This might ease coding
from time to time, especially if you call a function that needs to lock the mutex when you already hold the
mutex.
And the timeout gives a thread a chance to try to get the lock for a while, but then bail out if it can’t get it in
that timeframe. You use the mtx_timedlock() function with mtx_timed mutexes.
Return Value
Returns thrd_success in a perfect world, and potentially thrd_error in an imperfect one.
Example
General-purpose mutex example here, but you can see the mtx_init() down at the top of main():
1 #include <stdio.h>
2 #include <threads.h>
3
4 cnd_t condvar;
5 mtx_t mutex;
6
13 mtx_lock(&mutex);
14
17
18 mtx_unlock(&mutex);
19
20 return 0;
21 }
22
23 #define THREAD_COUNT 5
24
25 int main(void)
26 {
27 thrd_t t[THREAD_COUNT];
28
Output:
Thread: I got 0!
Thread: I got 1!
Thread: I got 2!
Thread: I got 3!
Thread: I got 4!
See Also
mtx_destroy()
27.10 mtx_lock()
Acquire a lock on a mutex
Synopsis
#include <threads.h>
Description
If you’re a thread and want to enter a critical section, do I have the function for you!
A thread that calls this function will wait until it can acquire the mutex, then it will grab it, wake up, and run!
If the mutex is recursive and is already locked by this thread, it will be locked again and the lock count will
increase. If the mutex is not recursive and the thread already holds it, this call will error out.
Chapter 27. <threads.h> Multithreading Functions 323
Return Value
Returns thrd_success on goodness and thrd_error on badness.
Example
General-purpose mutex example here, but you can see the mtx_lock() in the run() function:
1 #include <stdio.h>
2 #include <threads.h>
3
4 cnd_t condvar;
5 mtx_t mutex;
6
18 mtx_unlock(&mutex);
19
20 return 0;
21 }
22
23 #define THREAD_COUNT 5
24
25 int main(void)
26 {
27 thrd_t t[THREAD_COUNT];
28
Output:
Thread: I got 0!
Thread: I got 1!
Thread: I got 2!
Thread: I got 3!
Thread: I got 4!
Chapter 27. <threads.h> Multithreading Functions 324
See Also
mtx_unlock(), mtx_trylock(), mtx_timedlock()
27.11 mtx_timedlock()
Lock a mutex allowing for timeout
Synopsis
#include <threads.h>
Description
This is just like mtx_lock() except you can add a timeout if you don’t want to wait forever.
The timeout is specified as an absolute UTC time since Epoch. You can get this with the timespec_get()
function and then add values on to the result to timeout later than now, as shown in the example.
Beware that you can’t have more than 999999999 nanoseconds in the tv_nsec field of the struct time-
spec. Mod those so they stay in range.
Return Value
If everything works and the mutex is obtained, returns thrd_success. If a timeout happens first, returns
thrd_timedout.
Example
This example has a thread wait on a mutex for a maximum of 1.75 seconds. And it always times out because
no one ever sends a signal.
1 #include <stdio.h>
2 #include <time.h>
3 #include <threads.h>
4
5 mtx_t mutex;
6
19
27 switch (r) {
28 case thrd_success:
29 printf("Thread: grabbed lock!\n");
30 break;
31
32 case thrd_timedout:
33 printf("Thread: timed out!\n");
34 break;
35
36 case thrd_error:
37 printf("Thread: Some kind of error\n");
38 break;
39 }
40
41 mtx_unlock(&mutex);
42
43 return 0;
44 }
45
46 int main(void)
47 {
48 thrd_t t;
49
50 mtx_init(&mutex, mtx_plain);
51
52 mtx_lock(&mutex);
53
60 mtx_unlock(&mutex);
61
62 thrd_join(t, NULL);
63
64 mtx_destroy(&mutex);
65 }
Output:
Main creating thread
Thread: waiting for lock...
Thread: timed out!
Chapter 27. <threads.h> Multithreading Functions 326
See Also
mtx_lock(), mtx_trylock(), timespec_get()
27.12 mtx_trylock()
Try to lock a mutex, returning if not possible
Synopsis
#include <threads.h>
Description
This works just like mtx_lock except that it returns instantly if a lock can’t be obtained.
The spec notes that there’s a chance that mtx_trylock() might spuriously fail with thrd_busy even if there
are no other threads holding the lock. I’m not sure why this is, but you should defensively code against it.
Return Value
Returns thrd_success if all’s well. Or thrd_busy if some other thread holds the lock. Or thrd_error,
which means something went right. I mean “wrong”.
Example
1 #include <stdio.h>
2 #include <time.h>
3 #include <threads.h>
4
5 mtx_t mutex;
6
13 switch (r) {
14 case thrd_success:
15 printf("Thread %d: grabbed lock!\n", id);
16 break;
17
18 case thrd_busy:
19 printf("Thread %d: lock already taken :(\n", id);
20 return 1;
21
22 case thrd_error:
23 printf("Thread %d: Some kind of error\n", id);
24 return 2;
Chapter 27. <threads.h> Multithreading Functions 327
25 }
26
27 mtx_unlock(&mutex);
28
29 return 0;
30 }
31
32 #define THREAD_COUNT 5
33
34 int main(void)
35 {
36 thrd_t t[THREAD_COUNT];
37 int id[THREAD_COUNT];
38
39 mtx_init(&mutex, mtx_plain);
40
49 mtx_destroy(&mutex);
50 }
See Also
mtx_lock(), mtx_timedlock(), mtx_unlock()
27.13 mtx_unlock()
Free a mutex when you’re done with the critical section
Synopsis
#include <threads.h>
Description
After you’ve done all the dangerous stuff you have to do, wherein the involved threads should not be stepping
on each other’s toes… you can free up your stranglehold on the mutex by calling mtx_unlock().
Return Value
Returns thrd_success on success. Or thrd_error on error. It’s not very original in this regard.
Example
General-purpose mutex example here, but you can see the mtx_unlock() in the run() function:
1 #include <stdio.h>
2 #include <threads.h>
3
4 cnd_t condvar;
5 mtx_t mutex;
6
13 mtx_lock(&mutex);
14
20 return 0;
21 }
22
23 #define THREAD_COUNT 5
24
25 int main(void)
26 {
27 thrd_t t[THREAD_COUNT];
28
29 mtx_init(&mutex, mtx_plain);
30
37 mtx_destroy(&mutex);
38 }
Output:
Thread: I got 0!
Thread: I got 1!
Chapter 27. <threads.h> Multithreading Functions 329
Thread: I got 2!
Thread: I got 3!
Thread: I got 4!
See Also
mtx_lock(), mtx_timedlock(), mtx_trylock()
27.14 thrd_create()
Create a new thread of execution
Synopsis
#include <threads.h>
Description
Now you have the POWER!
Right?
This is how you launch new threads to make your program do multiple things at once2 !
In order to make this happen, you need to pass a pointer to a thrd_t that will be used to represent the thread
you’re spawning.
That thread will start running the function you pass a pointer to in func. This is a value of type
thrd_start_t, which is a pointer to a function that returns an int and takes a single void* as a parameter,
i.e.:
int thread_run_func(void *arg)
And, as you might have guessed, the pointer you pass to thrd_create() for the arg parameter is passed on
to the func function. This is how you can give additional information to the thread when it starts up.
Of course, for arg, you have to be sure to pass a pointer to an object that is thread-safe or per-thread.
If the thread returns from the function, it exits just as if it had called thrd_exit().
Finally, the value that the func function returns can be picked up by the parent thread with thrd_join().
Return Value
In the case of goodness, returns thrd_success. If you’re out of memory, will return thrd_nomem. Other-
wise, thrd_error.
Example
2
Well, as at least as many things as you have free cores. Your OS will schedule them as it can.
Chapter 27. <threads.h> Multithreading Functions 330
1 #include <stdio.h>
2 #include <threads.h>
3
10 return id;
11 }
12
13 #define THREAD_COUNT 5
14
15 int main(void)
16 {
17 thrd_t t[THREAD_COUNT];
18 int id[THREAD_COUNT]; // One of these per thread
19
28 thrd_join(t[i], &res);
29
See Also
thrd_exit(), thrd_join()
Chapter 27. <threads.h> Multithreading Functions 331
27.15 thrd_current()
Get the ID of the calling thread
Synopsis
#include <threads.h>
thrd_t thrd_current(void);
Description
Each thread has an opaque ID of type thrd_t. This is the value we see get initialized when we call
thrd_create().
But what if you want to get the ID of the currently running thread?
No problem! Just call this function and it will be returned to you.
Why? Who knows!
Well, to be honest, I could see it being used a couple places.
1. You could use it to have a thread detach itself with thrd_detach(). I’m not sure why you’d want to
do this, however.
2. You could use it to compare this thread’s ID with another you have stored in a variable somewhere by
using the thrd_equal() function. Seems like the most legit use.
3. …
4. Profit!
If anyone has another use, please let me know.
Return Value
Returns the calling thread’s ID.
Example
Here’s a general example that shows getting the current thread ID and comparing it to a previously-recorded
thread ID and taking exciting action based on the result! Starring Arnold Schwarzenegger!
1 #include <stdio.h>
2 #include <threads.h>
3
4 thrd_t first_thread_id;
5
12 if (thrd_equal(my_id, first_thread_id))
13 printf("I'm the first thread!\n");
14 else
15 printf("I'm not the first!\n");
16
Chapter 27. <threads.h> Multithreading Functions 332
17 return 0;
18 }
19
20 int main(void)
21 {
22 thrd_t t;
23
27 thrd_join(first_thread_id, NULL);
28 thrd_join(t, NULL);
29 }
Output:
Come on, you got what you want, Cohaagen! Give deez people ay-ah!
No, wait, that’s an Arnold Schwarzenegger quote from Total Recall, one of the best science fiction films of
all time. Watch it now and then come back to finish this reference page.
Man–what an ending! And Johnny Cab? So excellent. Anyway!
Output:
I'm the first thread!
I'm not the first!
See Also
thrd_equal(), thrd_detach()
27.16 thrd_detach()
Automatically clean up threads when they exit
Synopsis
#include <threads.h>
Description
Normally you have to thrd_join() to get resources associated with a deceased thread cleaned up. (Most
notably, its exit status is still floating around waiting to get picked up.)
But if you call thrd_detach() on the thread first, manual cleanup isn’t necessary. They just exit and are
cleaned up by the OS.
(Note that when the main thread dies, all the threads die in any case.)
Return Value
thrd_success if the thread successfully detaches, thrd_error otherwise.
Chapter 27. <threads.h> Multithreading Functions 333
Example
1 #include <stdio.h>
2 #include <threads.h>
3
4 thrd_t first_thread_id;
5
10 printf("Thread running!\n");
11
12 return 0;
13 }
14
15 #define THREAD_COUNT 5
16
17 int main(void)
18 {
19 thrd_t t;
20
26 // No need to thrd_join()!
27
See Also
thrd_join(), thrd_exit()
27.17 thrd_equal()
Compare two thread descriptors for equality
Synopsis
#include <threads.h>
Description
If you have two thread descriptors in thrd_t variables, you can test them for equality with this function.
Chapter 27. <threads.h> Multithreading Functions 334
For example, maybe one of the threads has special powers the others don’t, and the run function needs to be
able to tell them apart, as in the example.
Return Value
Returns non-zero if the threads are equal. Returns 0 if they’re not.
Example
Here’s a general example that shows getting the current thread ID and comparing it to a previously-recorded
thread ID and taking boring action based on the result.
1 #include <stdio.h>
2 #include <threads.h>
3
4 thrd_t first_thread_id;
5
17 return 0;
18 }
19
20 int main(void)
21 {
22 thrd_t t;
23
27 thrd_join(first_thread_id, NULL);
28 thrd_join(t, NULL);
29 }
Output:
I'm the first thread!
I'm not the first!
See Also
thrd_current()
Chapter 27. <threads.h> Multithreading Functions 335
27.18 thrd_exit()
Stop and exit this thread
Synopsis
#include <threads.h>
Description
A thread commonly exits by returning from its run function. But if it wants to exit early (perhaps from deeper
in the call stack), this function will get that done.
The res code can be picked up by a thread calling thrd_join(), and is equivalent to returning a value from
the run function.
Like with returning from the run function, this will also properly clean up all the thread-specific storage
associated with this thread—all the destructors for the threads TSS variables will be called. If there are any
remaining TSS variables with destructors after the first round of destruction3 , the remaining destructors will
be called. This happens repeatedly until there are no more, or the number of rounds of carnage reaches
TSS_DTOR_ITERATIONS.
Return Value
This function never returns because the thread calling it is killed in the process. Trippy!
Example
Threads in this example exit early with result 22 if they get a NULL value for arg.
1 #include <stdio.h>
2 #include <threads.h>
3
4 thrd_t first_thread_id;
5
10 if (arg == NULL)
11 thrd_exit(22);
12
13 return 0;
14 }
15
16 #define THREAD_COUNT 5
17
18 int main(void)
19 {
20 thrd_t t[THREAD_COUNT];
3
For example, if a destructor caused more variables to be set.
Chapter 27. <threads.h> Multithreading Functions 336
21
25
Output:
Thread 0 exited with code 0
Thread 1 exited with code 0
Thread 2 exited with code 22
Thread 3 exited with code 0
Thread 4 exited with code 0
See Also
thrd_join()
27.19 thrd_join()
Wait for a thread to exit
Synopsis
#include <threads.h>
Description
When a parent thread fires off some child threads, it can wait for them to complete with this call
Return Value
Example
Threads in this example exit early with result 22 if they get a NULL value for arg. The parent thread picks
up this result code with thrd_join().
1 #include <stdio.h>
2 #include <threads.h>
3
4 thrd_t first_thread_id;
5
7 {
8 (void)arg;
9
10 if (arg == NULL)
11 thrd_exit(22);
12
13 return 0;
14 }
15
16 #define THREAD_COUNT 5
17
18 int main(void)
19 {
20 thrd_t t[THREAD_COUNT];
21
25
Output:
Thread 0 exited with code 0
Thread 1 exited with code 0
Thread 2 exited with code 22
Thread 3 exited with code 0
Thread 4 exited with code 0
See Also
thrd_exit()
27.20 thrd_sleep()
Sleep for a specific number of seconds and nanoseconds
Synopsis
#include <threads.h>
Description
This function puts the current thread to sleep for a while4 allowing other threads to run.
The calling thread will wake up after the time has elapsed, or if it gets interrupted by a signal or something.
If it doesn’t get interrupted, it’ll sleep at least as long as you asked. Maybe a tad longer. You know how hard
it can be to get out of bed.
The structure looks like this:
struct timespec {
time_t tv_sec; // Seconds
long tv_nsec; // Nanoseconds (billionths of a second)
};
Don’t set tv_nsec greater than 999,999,999. I can’t see what officially happens if you do, but on my system
thrd_sleep() returns -2 and fails.
Return Value
Returns 0 on timeout, or -1 if interrupted by a signal. Or any negative value on some other error. Weirdly,
the spec allows this “other error negative value” to also be -1, so good luck with that.
Example
1 #include <stdio.h>
2 #include <threads.h>
3
4 int main(void)
5 {
6 // Sleep for 3.25 seconds
7 thrd_sleep(&(struct timespec){.tv_sec=3, .tv_nsec=250000000}, NULL);
8
9 return 0;
10 }
See Also
thrd_yield()
27.21 thrd_yield()
Stop running that other threads might run
Synopsis
#include <threads.h>
void thrd_yield(void);
4
Unix-like systems have a sleep() syscall that sleeps for an integer number of seconds. But thrd_sleep() is likely more portable
and gives subsecond resolution, besides!
Chapter 27. <threads.h> Multithreading Functions 339
Description
If you have a thread that’s hogging the CPU and you want to give your other threads time to run, you can
call thrd_yield(). If the system sees fit, it will put the calling thread to sleep and one of the other threads
will run instead.
It’s a good way to be “polite” to the other threads in your program if you want the encourage them to run
instead.
Return Value
Returns nothing!
Example
This example’s kinda poor because the OS is probably going to reschedule threads on the output anyway, but
it gets the point across.
The main thread is giving other threads a chance to run after every block of dumb work it does.
1 #include <stdio.h>
2 #include <threads.h>
3
8 if (main_thread) {
9 long int total = 0;
10
21 return 0;
22 }
23
24 #define THREAD_COUNT 10
25
26 int main(void)
27 {
28 thrd_t t[THREAD_COUNT];
29
36 return 0;
37 }
The output will vary from run to run. Notice that even after thrd_yield() other threads might not yet be
ready to run and the main thread will continue.
Main thread yielding
Main thread yielding
Main thread yielding
Other thread running!
Other thread running!
Other thread running!
Other thread running!
Main thread yielding
Other thread running!
Other thread running!
Main thread yielding
Main thread yielding
Main thread yielding
Other thread running!
Main thread yielding
Main thread yielding
Main thread yielding
Other thread running!
Other thread running!
See Also
thrd_sleep()
27.22 tss_create()
Create new thread-specific storage
Synopsis
#include <threads.h>
Description
This helps when you need per-thread storage of different values.
A common place this comes up is if you have a file scope variable that is shared between a bunch of functions
and often returned. That’s not threadsafe. One way to refactor is to replace it with thread-specific storage so
that each thread gets their own code and doesn’t step on other thread’s toes.
To make this work, you pass in a pointer to a tss_t key—this is the variable you will use in subsequent
tss_set() and tss_get() calls to set and get the value associated with the key.
The interesting part of this is the dtor destructor pointer of type tss_dtor_t. This is actually a pointer to
a function that takes a void* argument and returns void, i.e.
Chapter 27. <threads.h> Multithreading Functions 341
This function will be called per thread when the thread exits with thrd_exit() (or returns from the run
function).
It’s unspecified behavior to call this function while other threads’ destructors are running.
Return Value
Returns nothing!
Example
This is a general-purpose TSS example. Note the TSS variable is created near the top of main().
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <threads.h>
4
5 tss_t str;
6
7 void some_function(void)
8 {
9 // Retrieve the per-thread value of this string
10 char *tss_string = tss_get(str);
11
12 // And print it
13 printf("TSS string: %s\n", tss_string);
14 }
15
34 #define THREAD_COUNT 15
35
36 int main(void)
37 {
38 thrd_t t[THREAD_COUNT];
39
Output:
TSS string: thread 0! :)
TSS string: thread 2! :)
TSS string: thread 1! :)
TSS string: thread 5! :)
TSS string: thread 3! :)
TSS string: thread 6! :)
TSS string: thread 4! :)
TSS string: thread 7! :)
TSS string: thread 8! :)
TSS string: thread 9! :)
TSS string: thread 10! :)
TSS string: thread 13! :)
TSS string: thread 12! :)
TSS string: thread 11! :)
TSS string: thread 14! :)
See Also
tss_delete(), tss_set(), tss_get(), thrd_exit()
27.23 tss_delete()
Clean up a thread-specific storage variable
Synopsis
#include <threads.h>
Description
This is the opposite of tss_create(). You create (initialize) the TSS variable before using it, then, when
all the threads are done that need it, you delete (deinitialize/free) it with this.
This doesn’t call any destructors! Those are all called by thrd_exit()!
Return Value
Returns nothing!
Example
This is a general-purpose TSS example. Note the TSS variable is deleted near the bottom of main().
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <threads.h>
4
5 tss_t str;
6
7 void some_function(void)
8 {
9 // Retrieve the per-thread value of this string
10 char *tss_string = tss_get(str);
11
12 // And print it
13 printf("TSS string: %s\n", tss_string);
14 }
15
34 #define THREAD_COUNT 15
35
36 int main(void)
37 {
38 thrd_t t[THREAD_COUNT];
39
41 tss_create(&str, free);
42
Output:
TSS string: thread 0! :)
TSS string: thread 2! :)
TSS string: thread 1! :)
TSS string: thread 5! :)
TSS string: thread 3! :)
TSS string: thread 6! :)
TSS string: thread 4! :)
TSS string: thread 7! :)
TSS string: thread 8! :)
TSS string: thread 9! :)
TSS string: thread 10! :)
TSS string: thread 13! :)
TSS string: thread 12! :)
TSS string: thread 11! :)
TSS string: thread 14! :)
See Also
tss_create(), tss_set(), tss_get(), thrd_exit()
27.24 tss_get()
Get thread-specific data
Synopsis
#include <threads.h>
Description
Once you’ve set a variable with tss_set(), you can retrieve the value with tss_get()—just pass in the
key and you’ll get a pointer to the value back.
Don’t call this from a destructor.
Return Value
Returns the value stored for the given key, or NULL if there’s trouble.
Example
This is a general-purpose TSS example. Note the TSS variable is retrieved in some_function(), below.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <threads.h>
4
5 tss_t str;
6
7 void some_function(void)
8 {
9 // Retrieve the per-thread value of this string
10 char *tss_string = tss_get(str); // <-- GET THE VALUE
11
12 // And print it
13 printf("TSS string: %s\n", tss_string);
14 }
15
34 #define THREAD_COUNT 15
35
36 int main(void)
37 {
38 thrd_t t[THREAD_COUNT];
39
41 tss_create(&str, free);
42
Output:
TSS string: thread 0! :)
TSS string: thread 2! :)
TSS string: thread 1! :)
TSS string: thread 5! :)
TSS string: thread 3! :)
TSS string: thread 6! :)
TSS string: thread 4! :)
TSS string: thread 7! :)
TSS string: thread 8! :)
TSS string: thread 9! :)
TSS string: thread 10! :)
TSS string: thread 13! :)
TSS string: thread 12! :)
TSS string: thread 11! :)
TSS string: thread 14! :)
See Also
tss_set()
27.25 tss_set()
Set thread-specific data
Synopsis
#include <threads.h>
Description
Once you’ve set up your TSS variable with tss_create(), you can set it on a per thread basis with
tss_set().
key is the identifier for this data, and val is a pointer to it.
The destructor specified in tss_create() will be called for the value set when the thread exits.
Also, if there’s a destructor and there is already at value for this key in place, the destructor will not be called
for the already-existing value. In fact, this function will never cause a destructor to be called. So you’re on
your own, there—best clean up the old value before overwriting it with the new one.
Return Value
Returns thrd_success when happy, and thrd_error when not.
Example
This is a general-purpose TSS example. Note the TSS variable is set in run(), below.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <threads.h>
4
5 tss_t str;
6
7 void some_function(void)
8 {
9 // Retrieve the per-thread value of this string
10 char *tss_string = tss_get(str);
11
12 // And print it
13 printf("TSS string: %s\n", tss_string);
14 }
15
34 #define THREAD_COUNT 15
35
Chapter 27. <threads.h> Multithreading Functions 348
36 int main(void)
37 {
38 thrd_t t[THREAD_COUNT];
39
Output:
TSS string: thread 0! :)
TSS string: thread 2! :)
TSS string: thread 1! :)
TSS string: thread 5! :)
TSS string: thread 3! :)
TSS string: thread 6! :)
TSS string: thread 4! :)
TSS string: thread 7! :)
TSS string: thread 8! :)
TSS string: thread 9! :)
TSS string: thread 10! :)
TSS string: thread 13! :)
TSS string: thread 12! :)
TSS string: thread 11! :)
TSS string: thread 14! :)
See Also
tss_get()
Chapter 28
Function Description
clock() How much processor time has been used by this process
difftime() Compute the difference between two times
mktime() Convert a struct tm into a time_t
time() Get the current calendar time
timespec_get() Get a higher resolution time, probably now
asctime() Return a human-readable version of a struct tm
ctime() Return a human-readable version of a time_t
gmtime() Convert a calendar time into a UTC broken-down time
localtime() Convert a calendar time into a broken-down local time
strftime() Formatted date and time output
When it comes to time and C, there are two main types to look for:
• time_t holds a calendar time. This is an potentially opaque numeric type that represents an absolute
time that can be converted to UTC1 or local time.
• struct tm holds a broken-down time. This has things like the day of the week, the day of the month,
the hour, the minute, the second, etc.
On POSIX systems and Windows, time_t is an integer and represents the number of seconds that have
elapsed since January 1, 1970 at 00:00 UTC.
A struct tm contains the following fields:
struct tm {
int tm_sec; // seconds after the minute -- [0, 60]
int tm_min; // minutes after the hour -- [0, 59]
int tm_hour; // hours since midnight -- [0, 23]
int tm_mday; // day of the month -- [1, 31]
int tm_mon; // months since January -- [0, 11]
int tm_year; // years since 1900
int tm_wday; // days since Sunday -- [0, 6]
int tm_yday; // days since January 1 -- [0, 365]
int tm_isdst; // Daylight Saving Time flag
};
1
When you say GMT, unless you’re talking specifically about the time zone and not the time, you probably mean “UTC”.
349
Chapter 28. <time.h> Date and Time Functions 350
You can convert between the two with mktime(), gmtime(), and localtime().
You can print time information to strings with ctime(), asctime(), and strftime().
localtime(), gmtime(): These other two functions also return a pointer to a static memory region. They
both might return the same pointer. If you need thread safety, you’ll need a mutex across them. If you need
both results at once, copy the struct to another.
28.2 clock()
How much processor time has been used by this process
Synopsis
#include <time.h>
clock_t clock(void);
Description
Your processor is juggling a lot of things right now. Just because a process has been alive for 20 minutes
doesn’t mean that it used 20 minutes of “CPU time”.
Most of the time your average process spends asleep, and that doesn’t count toward the CPU time spent.
This function returns an opaque type representing the number of “clock ticks”2 the process has spent in
operation.
You can get the number of seconds out of that by dividing by the macro CLOCKS_PER_SEC. This is an integer,
so you will have to cast part of the expression to a floating type to get a fractional time.
Note that this is not the “wall clock time” of the program. If you want to get that loosely use time() and
difftime() (which might only offer 1-second resolution) or timespec_get() (which might only also offer
low resolution, but at least it might go to nanosecond level).
Return Value
Returns the amount of CPU time spent by this process. This comes back in a form that can be divided by
CLOCKS_PER_SEC to determine the time in seconds.
Example
2
The spec doesn’t actually say “clock ticks”, but I… am.
Chapter 28. <time.h> Date and Time Functions 351
1 #include <stdio.h>
2 #include <time.h>
3
11 int main(void)
12 {
13 printf("The 42nd Fibonacci Number is %lld\n", fib(42));
14
Output on my system:
The 42nd Fibonacci Number is 267914296
CPU time: 1.863078
See Also
time(), difftime(), timespec_get()
28.3 difftime()
Compute the difference between two times
Synopsis
#include <time.h>
Description
Since the time_t type is technically opaque, you can’t just straight-up subtract to get the difference between
two of them3 . Use this function to do it.
There is no guarantee as to the resolution of this difference, but it’s probably to the second.
Return Value
Returns the difference between two time_ts in seconds.
3
Unless you’re on a POSIX system where time_t is definitely an integer, in which case you can subtract. But you should still use
difftime() for maximum portability.
Chapter 28. <time.h> Date and Time Functions 352
Example
1 #include <stdio.h>
2 #include <time.h>
3
4 int main(void)
5 {
6 // April 12, 1982 and change
7 struct tm time_a = { .tm_year=82, .tm_mon=3, .tm_mday=12,
8 .tm_hour=4, .tm_min=00, .tm_sec=04, .tm_isdst=-1,
9 };
10
Output:
1217996816.000000 seconds (38.596783 years) between events
See Also
time(), mktime()
28.4 mktime()
Convert a struct tm into a time_t
Synopsis
#include <time.h>
Description
If you have a local date and time and want it converted to a time_t (so that you can difftime() it or
whatever), you can convert it with this function.
Basically you fill out the fields in your struct tm in local time and mktime() will convert those to the
UTC time_t equivalent.
Chapter 28. <time.h> Date and Time Functions 353
A couple notes:
• Don’t bother filling out tm_wday or tm_yday. mktime() will fill these out for you.
• You can set tm_isdst to 0 to indicate your time isn’t Daylight Saving Time (DST), 1 to indicate it is,
and -1 to have mktime() fill it in according to your locale’s preference.
If you need input in UTC, see the non-standard functions timegm()4 for Unix-likes and _mkgmtime()5 for
Windows.
Return Value
Returns the local time in the struct tm as a time_t calendar time.
Returns (time_t)(-1) on error.
Example
In the following example, we have mktime() tell us if that time was DST or not.
1 #include <stdio.h>
2 #include <time.h>
3
4 int main(void)
5 {
6 struct tm broken_down_time = {
7 .tm_year=82, // years since 1900
8 .tm_mon=3, // months since January -- [0, 11]
9 .tm_mday=12, // day of the month -- [1, 31]
10 .tm_hour=4, // hours since midnight -- [0, 23]
11 .tm_min=00, // minutes after the hour -- [0, 59]
12 .tm_sec=04, // seconds after the minute -- [0, 60]
13 .tm_isdst=-1, // Daylight Saving Time flag
14 };
15
4
https://man.archlinux.org/man/timegm.3.en
5
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/mkgmtime-mkgmtime32-mkgmtime64?view=msvc-160
Chapter 28. <time.h> Date and Time Functions 354
See Also
localtime(), gmtime()
28.5 time()
Get the current calendar time
Synopsis
#include <time.h>
Description
Returns the current calendar time right now. I mean, now. No, now!
If timer is not NULL, it gets loaded with the current time, as well.
This can be converted into a struct tm with localtime() or gmtime(), or printed directly with ctime().
Return Value
Returns the current calendar time. Also loads timer with the current time if it’s not NULL.
Or returns (time_t)(-1) if the time isn’t available because you’ve fallen out of the space-time continuum
and/or the system doesn’t support times.
Example
1 #include <stdio.h>
2 #include <time.h>
3
4 int main(void)
5 {
6 time_t now = time(NULL);
7
Example output:
The local time is Mon Mar 1 18:45:14 2021
See Also
localtime(), gmtime(), ctime()
Chapter 28. <time.h> Date and Time Functions 355
28.6 timespec_get()
Get a higher resolution time, probably now
Synopsis
#include <time.h>
Description
This function loads the current time UTC (unless directed otherwise) into the given struct timespec, ts.
That structure has two fields:
struct timespec {
time_t tv_sec; // Whole seconds
long tv_nsec; // Nanoseconds, 0-999999999
}
Nanoseconds are billionths of a second. You can divide by 1000000000.0 to convert to seconds.
The base parameter has only one defined value, by the spec: TIME_UTC. So portably make it that. This will
load ts with the current time in seconds since a system-defined Epoch6 , often January 1, 1970 at 00:00 UTC.
Your implementation might define other values for base.
Return Value
When base is TIME_UTC, loads ts with the current UTC time.
On success, returns base, valid values for which will always be non-zero. On error, returns 0.
Example
1 struct timespec ts;
2
3 timespec_get(&ts, TIME_UTC);
4
Example output:
1614654187 s, 825540756 ns
1614654187.825541 seconds since epoch
Here’s a helper function to add values to a struct timespec that handles negative values and nanosecond
overflow.
#include <stdlib.h>
if (qr.rem < 0) {
nsec = 1000000000L + qr.rem;
sec += qr.quot - 1;
} else {
nsec = qr.rem;
sec += qr.quot;
}
ts->tv_sec = sec;
ts->tv_nsec = nsec;
return ts;
}
And here are some functions to convert from long double to struct timespec and back, just in case you
like thinking in decimals. This is more limited in significant figures than using the integer values.
#include <math.h>
return ts;
}
See Also
time(), mtx_timedlock(), cnd_timedwait()
Chapter 28. <time.h> Date and Time Functions 357
28.7 asctime()
Return a human-readable version of a struct tm
Synopsis
#include <time.h>
Description
This takes a time in a struct tm and returns a string with that date in the form:
Sun Sep 16 01:03:52 1973
with a newline included at the end, rather unhelpfully. (strftime() will give you more flexibility.)
It’s just like ctime(), except it takes a struct tm instead of a time_t.
WARNING: This function returns a pointer to a static char* region that isn’t thread-safe and might be
shared with the ctime() function. If you need thread safety, use strftime() or use a mutex that covers
ctime() and asctime().
Return Value
Returns a pointer to the human-readable date string.
Example
1 #include <stdio.h>
2 #include <time.h>
3
4 int main(void)
5 {
6 time_t now = time(NULL);
7
Sample output:
Local: Mon Mar 1 21:17:34 2021
UTC : Tue Mar 2 05:17:34 2021
See Also
ctime(), localtime(), gmtime()
Chapter 28. <time.h> Date and Time Functions 358
28.8 ctime()
Return a human-readable version of a time_t
Synopsis
#include <time.h>
Description
This takes a time in a time_t and returns a string with the local time and date in the form:
Sun Sep 16 01:03:52 1973
with a newline included at the end, rather unhelpfully. (strftime() will give you more flexibility.)
It’s just like asctime(), except it takes a time_t instead of a struct tm.
WARNING: This function returns a pointer to a static char* region that isn’t thread-safe and might be
shared with the asctime() function. If you need thread safety, use strftime() or use a mutex that covers
ctime() and asctime().
Return Value
A pointer to the human-readable local time and data string.
Example
1 time_t now = time(NULL);
2
Sample output:
Local: Mon Mar 1 21:32:23 2021
See Also
asctime()
28.9 gmtime()
Convert a calendar time into a UTC broken-down time
Chapter 28. <time.h> Date and Time Functions 359
Synopsis
#include <time.h>
Description
If you have a time_t, you can run it through this function to get a struct tm back full of the corresponding
broken-down UTC time information.
This is just like localtime(), except it does UTC instead of local time.
Once you have that struct tm, you can feed it to strftime() to print it out.
WARNING: This function returns a pointer to a static struct tm* region that isn’t thread-safe and might
be shared with the localtime() function. If you need thread safety use a mutex that covers gmtime() and
localtime().
Return Value
Returns a pointer to the broken-down UTC time, or NULL if it can’t be obtained.
Example
1 #include <stdio.h>
2 #include <time.h>
3
4 int main(void)
5 {
6 time_t now = time(NULL);
7
Sample output:
UTC : Tue Mar 2 05:40:05 2021
Local: Mon Mar 1 21:40:05 2021
See Also
localtime(), asctime(), strftime()
28.10 localtime()
Convert a calendar time into a broken-down local time
Synopsis
Chapter 28. <time.h> Date and Time Functions 360
#include <time.h>
Description
If you have a time_t, you can run it through this function to get a struct tm back full of the corresponding
broken-down local time information.
This is just like gmtime(), except it does local time instead of UTC.
Once you have that struct tm, you can feed it to strftime() to print it out.
WARNING: This function returns a pointer to a static struct tm* region that isn’t thread-safe and
might be shared with the gmtime() function. If you need thread safety use a mutex that covers gmtime()
and localtime().
Return Value
Returns a pointer to the broken-down local time, or NULL if it can’t be obtained.
Example
1 #include <stdio.h>
2 #include <time.h>
3
4 int main(void)
5 {
6 time_t now = time(NULL);
7
Sample output:
Local: Mon Mar 1 21:40:05 2021
UTC : Tue Mar 2 05:40:05 2021
See Also
gmtime(), asctime(), strftime()
28.11 strftime()
Formatted date and time output
Synopsis
#include <time.h>
Description
This is the sprintf() of date and time functions. It’ll take a struct tm and produce a string in just about
whatever form you desire, for example:
2021-03-01
Monday, March 1 at 9:54 PM
It's Monday!
It’s a super flexible version of asctime(). And thread-safe, besides, since it doesn’t rely on a static buffer
to hold the results.
Basically what you do is give it a destination, s, and its max size in bytes in maxsize. Also, provide a
format string that’s analogous to printf()’s format string, but with different format specifiers. And lastly,
a struct tm with the broken-down time information to use for printing.
The format string works like this, for example:
"It's %A, %B %d!"
Which produces:
It's Monday, March 1!
The %A is the full day-of-week name, the %B is the full month name, and the %d is the day of the month.
strftime() substitutes the right thing to produce the result. Brilliant!
Specifier Description
%a Locale’s abbreviated weekday name. [tm_wday]
%A Locale’s full weekday name. [tm_wday]
%b Locale’s abbreviated month name. [tm_mon]
%B Locale’s full month name. [tm_mon]
%c Locale’s appropriate date and time representation.
%C Year divided by 100 and truncated to an integer, as a decimal number (00–99). [tm_year]
%d Day of the month as a decimal number (01–31). [tm_mday]
%D Equivalent to "%m/%d/%y". [tm_mon, tm_mday, tm_year]
%e Day of the month as a decimal number (1–31); a single digit is preceded by a space.
[tm_mday]
%F Equivalent to “%Y-%m-%d” (the ISO 8601 date format). [tm_year, tm_mon, tm_mday]
%g Last 2 digits of the week-based year (see below) as a decimal number (00–99). [tm_year,
tm_wday, tm_yday]
%G Week-based year (see below) as a decimal number (e.g., 1997). [tm_year, tm_wday,
tm_yday]
%h Equivalent to “%b”. [tm_mon]
%H Hour (24-hour clock) as a decimal number (00–23). [tm_hour]
%I Hour (12-hour clock) as a decimal number (01–12). [tm_hour]
%j Day of the year as a decimal number (001–366). [tm_yday]
%m Month as a decimal number (01–12).
%M Minute as a decimal number (00–59). [tm_min]
%n A new-line character.
Chapter 28. <time.h> Date and Time Functions 362
Specifier Description
%p Locale’s equivalent of the AM/PM designations associated with a 12-hour clock. [tm_hour]
%r Locale’s 12-hour clock time. [tm_hour, tm_min, tm_sec]
%R Equivalent to "%H:%M". [tm_hour, tm_min]
%S Second as a decimal number (00–60). [tm_sec]
%t A horizontal-tab character.
%T Equivalent to "%H:%M:%S" (the ISO 8601 time format). [tm_hour, tm_min, tm_sec]
%u ISO 8601 weekday as a decimal number (1–7), where Monday is 1. [tm_wday]
%U Week number of the year (the first Sunday as the first day of week 1) as a decimal number
(00–53). [tm_year, tm_wday, tm_yday]
%V ISO 8601 week number (see below) as a decimal number (01–53). [tm_year, tm_wday,
tm_yday]
%w Weekday as a decimal number (0–6), where Sunday is 0.
%W Week number of the year (the first Monday as the first day of week 1) as a decimal number
(00–53). [tm_year, tm_wday, tm_yday]
%x Locale’s appropriate date representation.
%X Locale’s appropriate time representation.
%y Last 2 digits of the year as a decimal number (00–99). [tm_year]
%Y Year as a decimal number (e.g., 1997). [tm_year]
%z Offset from UTC in the ISO 8601 format "-0430" (meaning 4 hours 30 minutes behind UTC,
west of Greenwich), or by no characters if no time zone is determinable. [tm_isdst]
%Z Locale’s time zone name or abbreviation, or by no characters if no time zone is determinable.
[tm_isdst]
%% A plain ol’ %
Specifier Description
%a The first three characters of %A.
%A One of Sunday, Monday, … , Saturday.
%b The first three characters of %B.
%B One of January, February, … , December.
%c Equivalent to %a %b %e %T %Y.
%p One of AM or PM.
%r Equivalent to %I:%M:%S %p.
%x Equivalent to %m/%d/%y.
7
https://en.wikipedia.org/wiki/ISO_week_date
Chapter 28. <time.h> Date and Time Functions 363
Specifier Description
%X Equivalent to %T.
%Z Implementation-defined.
There are additional variants of the format specifiers that indicate you want to use a locale’s alternative format.
These don’t exist for all locales. It’s one of the format specifies above, with either an E or O prefix:
%Ec %EC %Ex %EX %Ey %EY %Od %Oe %OH %OI
%Om %OM %OS %Ou %OU %OV %Ow %OW %Oy
Return Value
Returns the total number of bytes put into the result string, not including the NUL terminator.
If the result doesn’t fit in the string, zero is returned and the value in s is indeterminate.
Example
1 #include <stdio.h>
2 #include <time.h>
3
4 int main(void)
5 {
6 char s[128];
7 time_t now = time(NULL);
8
See Also
ctime(), asctime()
Chapter 29
Function Description
c16rtomb() Convert a char16_t to a multibyte character
c32rtomb() Convert a char32_t to a multibyte character
mbrtoc16() Convert a multibyte character to a char16_t
mbrtoc32() Convert a multibyte character to a char32_t
These functions are restartable, meaning multiple threads can safely call them at once. They handle this by
having their own conversion state variable (of type mbstate_t) per call.
29.1 Types
This header file defines four types.
Type Description
char16_t Type to hold 16-bit characters
char32_t Type to hold 32-bit characters
mbstate_t Holds the conversion state for restartable funcitons (also defined in <wchar.h>)
size_t To hold various counts (also defined in <stddef.h>)
String literals for the character types are u for char16_t and U for char32_t.
char16_t *str1 = u"Hello, world!";
char32_t *str2 = U"Hello, world!";
Note that char16_t and char32_t might contain Unicode. Or not. If __STDC_UTF_16__ or
__STDC_UTF_32__ is defined as 1, then char16_t and char32_t use Unicode, respectively. Other-
wise they don’t and the actual value stored depend on the locale. And if you’re not using Unicode, you have
my commiserations.
365
Chapter 29. <uchar.h> Unicode utility functions 366
29.2 OS X issue
This header file doesn’t exist on OS X—bummer. If you just want the types, you can:
#include <stdint.h>
Synopsis
#include <uchar.h>
Description
Given a source string s and a destination buffer pc16 (or pc32 for mbrtoc32()), convert the first character
of the source to char16_ts (or char32_ts for mbrtoc32()).
Basically you have a regular character and you want it as char16_t or char32_t. Use these functions to do
it. Note that only one character is converted no matter how many characters in s.
As the functions scan s, you don’t want them to overrun the end. So you pass in n as the maximum number
of bytes to inspect. The functions will quit after that many bytes or when they have a complete multibyte
character, whichever comes first.
Since they’re restartable, pass in a conversion state variable for the functions to do their work.
And the result will be placed in pc16 (or pc32 for mbrtoc32()).
Return Value
When successful this function returns a number between 1 and n inclusive representing the number of bytes
that made up the multibyte character.
Or, also in the success category, they can return 0 if the source character is the NUL character (value 0).
When not entirely successful, they can return a variety of codes. These are all of type size_t, but negative
values cast to that type.
Case (size_t)(-3) is an odd one. Basically there are some characters that can’t be represented with 16 bits
and so can’t be stored in a char16_t. These characters are store in something called (in the Unicode world)
surrogate pairs. That is, there are two 16-bit values back to back that represent a larger Unicode value.
For example, if you want to read the Unicode character \U0001fbc5 (which is a stick figure1 —I’m just not
putting it in the text because my font doesn’t render it) that’s more than 16 bits. But each call to mbrtoc16()
only returns a single char16_t!
So subsequent calls to mbrtoc16() resolves the next value in the surrogate pair and returns (size_t)(-3)
to let you know this has happened.
You can also pass NULL for pc16 or pc32. This will cause no result to be stored, but you can use it if you’re
only interested in the return value from the functions.
Finally, if you pass NULL for s, the call is equivalent to:
mbrtoc16(NULL, "", 1, ps)
Since the character is a NUL in that case, this has the effect of setting the state in ps to the initial conversion
state.
Example
Normal use case example where we get the first two character values from the multibyte string "€Zillion":
#include <uchar.h>
#include <stdio.h> // for printf()
#include <locale.h> // for setlocale()
#include <string.h> // for memset()
int main(void)
{
char *s = "\u20acZillion"; // 20ac is "€"
char16_t pc16;
size_t r;
mbstate_t mbs;
setlocale(LC_ALL, "");
memset(&mbs, 0, sizeof mbs);
1
https://en.wikipedia.org/wiki/Symbols_for_Legacy_Computing
Chapter 29. <uchar.h> Unicode utility functions 368
Example with a surrogate pair. In this case we read plenty to get the entire character, but the result must be
stored in two char16_ts, requiring two calls to get them both.
1 #include <uchar.h>
2 #include <stdio.h> // for printf()
3 #include <string.h> // for memset()
4 #include <locale.h> // for setlocale()
5
6 int main(void)
7 {
8 char *s = "\U0001fbc5*"; // Stick figure glyph, more than 16 bits
9 char16_t pc16;
10 mbstate_t mbs;
11 size_t r;
12
13 setlocale(LC_ALL, "");
14 memset(&mbs, 0, sizeof mbs);
15
16 r = mbrtoc16(&pc16, s, 8, &mbs);
17
23 r = mbrtoc16(&pc16, s, 8, &mbs);
24
32 r = mbrtoc16(&pc16, s, 8, &mbs);
33
Output on my system, indicating the first character is represented by the pair (0xd83e, 0xdfc5) and the
second character is represented by 0x2a:
4
0xd83e
-3
0xdfc5
1
0x2a
Chapter 29. <uchar.h> Unicode utility functions 369
See Also
c16rtomb(), c32rtomb()
Synopsis
#include <uchar.h>
Description
If you have a character in a char16_t or char32_t, use these functions to convert them into a multibyte
character.
These functions figure out how many bytes are needed for the multibyte character in the current locale and
stores them in the buffer pointed to by s.
But how big to make that buffer? Luckily there is a macro to help: it needs be no larger than MB_CUR_MAX.
As a special case, if s is NULL, it’s the same as calling
c16rtomb(buf, L'\0', ps); // or...
c32rtomb(buf, L'\0', ps);
where buf is a buffer maintained by the system that you don’t have access to.
This has the effect of setting the ps state to the initial state.
Finally for surrogate pairs (where the character has been split into two char16_ts), you call this once with
the first of the pair—at this point, the function will return 0. Then you call it again with the second of the
pair, and the function will return the number of bytes and store the result in the array s.
Return Value
Returns the number of bytes stored in the array pointed to by s.
Returns 0 if processing is not yet complete for the current character, as in the case of surrogate pairs.
If there is an encoding error, the functions return (size_t)(-1) and errno is set to EILSEQ.
Example
1 #include <uchar.h>
2 #include <stdlib.h> // for MB_CUR_MAX
3 #include <stdio.h> // for printf()
4 #include <string.h> // for memset()
5 #include <locale.h> // for setlocale()
6
Chapter 29. <uchar.h> Unicode utility functions 370
7 int main(void)
8 {
9 char16_t c16 = 0x20ac; // Unicode for Euro symbol
10 char dest[MB_CUR_MAX];
11 size_t r;
12 mbstate_t mbs;
13
14 setlocale(LC_ALL, "");
15 memset(&mbs, 0, sizeof mbs); // Reset conversion state
16
17 // Convert
18 r = c16rtomb(dest, c16, &mbs);
19
Output on my system:
r == 3
dest == "€"
This is a more complex example that converts a large-valued character in a multibyte string into a surrogate
pair (as in the mbrtoc16() example, above) and then converts it back again into a multibyte string to print.
1 #include <uchar.h>
2 #include <stdlib.h> // for MB_CUR_MAX
3 #include <stdio.h> // for printf()
4 #include <string.h> // for memset()
5 #include <locale.h> // for setlocale()
6
7 int main(void)
8 {
9 char *src = "\U0001fbc5*"; // Stick figure glyph, more than 16 bits
10 char dest[MB_CUR_MAX];
11 char16_t surrogate0, surrogate1;
12 mbstate_t mbs;
13 size_t r;
14
15 setlocale(LC_ALL, "");
16 memset(&mbs, 0, sizeof mbs); // Reset conversion state
17
27 // Now reverse it
28 memset(&mbs, 0, sizeof mbs); // Reset conversion state
Chapter 29. <uchar.h> Unicode utility functions 371
29
See Also
mbrtoc16(), mbrtoc32()
Chapter 30
Function Description
btowc() Convert a single byte character to a wide character
fgetwc() Get a wide character from a wide stream
fgetws() Read a wide string from a wide stream
fputwc() Write a wide character to a wide stream
fputws() Write a wide string to a wide stream
fwide() Get or set the orientation of the stream
fwprintf() Formatted wide output to a wide stream
fwscanf() Formatted wide input from a wide stream
getwchar() Get a wide character from stdin
getwc() Get a wide character from stdin
mbrlen() Compute the number of bytes in a multibyte character restartably
mbrtowc() Convert multibyte to wide characters restartably
mbsinit() Test if an mbstate_t is in the initial conversion state
mbsrtowcs() Convert a multibyte string to a wide character string restartably
putwchar() Write a wide character to stdout
putwc() Write a wide character to stdout
swprintf() Formatted wide output to a wide string
swscanf() Formatted wide input from a wide string
ungetwc() Pushes a wide character back into the input stream
vfwprintf() Variadic formatted wide output to a wide stream
vfwscanf() Variadic formatted wide input from a wide stream
vswprintf() Variadic formatted wide output to a wide string
vswscanf() Variadic formatted wide input from a wide string
vwprintf() Variadic formatted wide output
vwscanf() Variadic formatted wide input
wcscat() Concatenate wide strings dangerously
wcschr() Find a wide character in a wide string
wcscmp() Compare wide strings
wcscoll() Compare two wide strings accounting for locale
wcscpy() Copy a wide string dangerously
wcscspn() Count characters not from a start at the front of a wide string
wcsftime() Formatted date and time output
wcslen() Returns the length of a wide string
wcsncat() Concatenate wide strings more safely
wcsncmp() Compare wide strings, length limited
372
Chapter 30. <wchar.h> Wide Character Handling 373
Function Description
wcsncpy() Copy a wide string more safely
wcspbrk() Search a wide string for one of a set of wide characters
wcsrchr() Find a wide character in a wide string from the end
wcsrtombs() Convert a wide character string to a multibyte string restartably
wcsspn() Count characters from a set at the front of a wide string
wcsstr() Find a wide string in another wide string
wcstod() Convert a wide string to a double
wcstof() Convert a wide string to a float
wcstok() Tokenize a wide string
wcstold() Convert a wide string to a long double
wcstoll() Convert a wide string to a long long
wcstol() Convert a wide string to a long
wcstoull() Convert a wide string to an unsigned long long
wcstoul() Convert a wide string to an unsigned long
wcsxfrm() Transform a wide string for comparing based on locale
wctob() Convert a wide character to a single byte character
wctombr() Convert wide to multibyte characters restartably
wmemcmp() Compare wide characters in memory
wmemcpy() Copy wide character memory
wmemmove() Copy wide character memory, potentially overlapping
wprintf() Formatted wide output
wscanf() Formatted wide input
These are the wide character variants of the functions found in <stdio.h>.
Remember that you can’t mix-and-match multibyte output functions (like printf()) with wide character
output functions (like wprintf()). The output stream has an orientation to either multibyte or wide that
gets set on the first I/O call to that stream. (Or it can be set with fwide().)
So choose one or the other and stick with it.
And you can specify wide character constants and string literals by prefixing L to the front of it:
wchar_t *s = L"Hello, world!";
wchar_t c = L'B';
This header also introduces a type wint_t that is used by the character I/O functions. It’s a type that can
hold any single wide character, but also the macro WEOF to indicate wide end-of-file.
Synopsis
#include <stdio.h> // For fwprintf()
#include <wchar.h>
Description
These are the wide versions of printf(), fprintf()](#man-printf), and [sprintf()‘.
See those pages for exact substantial usage.
These are the same except the format string is a wide character string instead of a multibyte string.
And that swprintf() is analogous to snprintf() in that they both take the size of the destination array as
an argument.
And one more thing: the precision specified for a %s specifier corresponds to the number of wide characters
printed, not the number of bytes. If you know of other difference, let me know.
Return Value
Returns the number of wide characters outputted, or -1 if there’s an error.
Example
1 #include <stdio.h>
2 #include <wchar.h>
3
4 int main(void)
5 {
6 char *mbs = "multibyte";
7 wchar_t *ws = L"wide";
8
11 double pi = 3.14159265358979;
12 wprintf(L"pi = %f\n", pi);
13 }
Output:
We're all wide for multibyte and wide!
pi = 3.141593
Chapter 30. <wchar.h> Wide Character Handling 375
See Also
printf(), vwprintf()
Synopsis
#include <stdio.h> // for fwscanf()
#include <wchar.h>
Description
These are the wide variants of scanf(), fscanf(), and sscanf().
See the scanf() page for all the details.
Return Value
Returns the number of items successfully scanned, or EOF on some kind of input failure.
Example
1 #include <stdio.h>
2 #include <wchar.h>
3
4 int main(void)
5 {
6 int quantity;
7 wchar_t item[100];
8
See Also
scanf(), vwscanf()
Synopsis
#include <stdio.h> // For vfwprintf()
#include <stdarg.h>
#include <wchar.h>
Description
These functions are the wide character variants of the vprintf(), functions. You can refer to that reference
page for more details.
Return Value
Returns the number of wide characters stored, or a negative value on error.
Example
In this example, we make our own version of wprintf() called wlogger() that timestamps output. Notice
how the calls to wlogger() have all the bells and whistles of wprintf().
1 #include <stdarg.h>
2 #include <wchar.h>
3 #include <time.h>
4
16 va_start(va, format);
Chapter 30. <wchar.h> Wide Character Handling 377
20 wprintf(L"\n");
21
22 return result;
23 }
24
25 int main(void)
26 {
27 int x = 12;
28 float y = 3.2;
29
30 wlogger(L"Hello!");
31 wlogger(L"x = %d and y = %.2f", x, y);
32 }
Output:
2021-03-30 04:25:49 : Hello!
2021-03-30 04:25:49 : x = 12 and y = 3.20
See Also
printf(), vprintf()
Synopsis
#include <stdio.h> // For vfwscanf()
#include <stdarg.h>
#include <wchar.h>
Description
These are the wide counterparts to the vscanf() collection of functions. See their reference page for details.
Return Value
Returns the number of items successfully scanned, or EOF on some kind of input failure.
Chapter 30. <wchar.h> Wide Character Handling 378
Example
I have to admit I was wracking my brain to think of when you’d ever want to use this. The best example I
could find was one on Stack Overflow1 that error-checks the return value from scanf() against the expected.
A variant of that is shown below.
1 #include <stdarg.h>
2 #include <wchar.h>
3 #include <assert.h>
4
9 va_start(va, format);
10 int count = vwscanf(format, va);
11 va_end(va);
12
16 return count;
17 }
18
19 int main(void)
20 {
21 int a, b;
22 float c;
23
See Also
wscanf()
Synopsis
#include <stdio.h> // For getwc() and fgetwc()
#include <wchar.h>
wint_t getwchar(void);
Description
These are the wide variants of fgetc().
fgetwc() and getwc() are identical except that getwc() might be implemented as a macro and is allowed
to evaluate stream multiple times.
getwchar() is identical to getwc() with stream set to stdin.
I don’t know why you’d ever use getwc() instead of fgetwc(), but if anyone knows, drop me a line.
Return Value
Returns the next wide character in the input stream. Return WEOF on end-of-file or error.
If an I/O error occurs, the error flag is also set on the stream.
If an invalid byte sequence is encountered, errno is set to ILSEQ.
Example
Reads all the characters from a file, outputting only the letter ’b’s it finds in the file:
1 #include <stdio.h>
2 #include <wchar.h>
3
4 int main(void)
5 {
6 FILE *fp;
7 wint_t c;
8
17 fclose(fp);
18 }
See Also
fputwc, fgetws, errno
30.7 fgetws()
Read a wide string from a file
Synopsis
#include <stdio.h>
#include <wchar.h>
Chapter 30. <wchar.h> Wide Character Handling 380
Description
This is the wide version of fgets(). See its reference page for details.
A wide NUL character is used to terminate the string.
Return Value
Returns s on success, or a NULL pointer on end-of-file or error.
Example
The following example reads lines from a file and prepends them with numbers:
1 #include <stdio.h>
2 #include <wchar.h>
3
6 int main(void)
7 {
8 FILE *fp;
9 wchar_t buf[BUF_SIZE];
10
13 int line_count = 0;
14
18 fclose(fp);
19 }
Example output for a file with these lines in them (without the prepended numbers):
0001: line 1
0002: line 2
0003: something
0004: line 4
See Also
fgetwc(), fgets()
Synopsis
#include <stdio.h> // For putwc() and fputwc()
#include <wchar.h>
Description
These are the wide character equivalents to the ‘fputc()’ group of functions. You can find more information
‘in that reference section’.
fputwc() and putwc() are identical except that putwc() might be implemented as a macro and is allowed
to evaluate stream multiple times.
putwchar() is identical to putwc() with stream set to stdin.
I don’t know why you’d ever use putwc() instead of fputwc(), but if anyone knows, drop me a line.
Return Value
Returns the wide character written, or WEOF on error.
If it’s an I/O error, the error flag will be set for the stream.
If it’s an encoding error, errno will be set to EILSEQ.
Example
Read all characters from a file, outputting only the letter ’b’s it finds in the file:
1 #include <stdio.h>
2 #include <wchar.h>
3
4 int main(void)
5 {
6 FILE *fp;
7 wint_t c;
8
17 fclose(fp);
18 }
See Also
fgetwc(), fputc(), errno
Chapter 30. <wchar.h> Wide Character Handling 382
30.9 fputws()
Write a wide string to a file
Synopsis
#include <stdio.h>
#include <wchar.h>
Description
This is the wide version of fputs().
Pass in a wide string and an output stream, and it will so be written.
Return Value
Returns a non-negative value on success, or EOF on error.
Example
1 #include <stdio.h>
2 #include <wchar.h>
3
4 int main(void)
5 {
6 fputws(L"Hello, world!\n", stdout);
7 }
See Also
fputwc() fputs()
30.10 fwide()
Get or set the orientation of the stream
Synopsis
#include <stdio.h>
#include <wchar.h>
Description
Streams can be either wide-oriented (meaning the wide functions are in use) or byte-oriented (that the regular
multibyte functions are in use). Or, before an orientation is chosen, unoriented.
There are two ways to set the orientation of an unoriented stream:
• Implicitly: just use a function like printf() (byte oriented) or wprintf() (wide oriented), and the
orientation will be set.
• Explicitly: use this function to set it.
You can set the orientation for the stream by passing different numbers to mode:
mode Description
0 Do not alter the orientation
-1 Set stream to byte-oriented
1 Set stream to wide-oriented
(I said -1 and 1 there, but really it could be any positive or negative number.)
Most people choose the wide or byte functions (printf() or wprintf()) and just start using them and never
use fwide() to set the orientation.
And once the orientation is set, you can’t change it. So you can’t use fwide() for that, either.
So what can you use it for?
You can test to see what orientation a stream is in by passing 0 as the mode and checking the return value.
Return Value
Returns greater than zero if the stream is wide-oriented.
Returns less than zero if the stream is byte-oriented.
Returns zero if the stream is unoriented.
Example
Example setting to byte-oriented:
1 #include <stdio.h>
2 #include <wchar.h>
3
4 int main(void)
5 {
6 printf("Hello world!\n"); // Implicitly set to byte
7
Output:
Hello world!
Stream is byte-oriented
1 #include <stdio.h>
2 #include <wchar.h>
3
4 int main(void)
5 {
6 wprintf(L"Hello world!\n"); // Implicitly set to wide
7
Output:
Hello world!
Stream is wide-oriented
30.11 ungetwc()
Pushes a wide character back into the input stream
Synopsis
#include <stdio.h>
#include <wchar.h>
Description
This is the wide character variant of ungetc().
It performs the reverse operation of fgetwc(), pushing a character back on the input stream.
The spec guarantees you can do this one time in a row. You can probably do it more times, but it’s up to the
implementation. If you do too many calls without an intervening read, an error could be returned.
Setting the file position discards any characters pushed by ungetwc() without being subsequently read.
The end-of-file flag is cleared after a successful call.
Return Value
Returns the value of the pushed character on success, or WEOF on failure.
Example
This example reads a piece of punctuation, then everything after it up to the next piece of punctuation. It
returns the leading punctuation, and stores the rest in a string.
1 #include <stdio.h>
2 #include <wctype.h>
3 #include <wchar.h>
4
Chapter 30. <wchar.h> Wide Character Handling 385
9 origpunct = fgetwc(fp);
10
24 return origpunct;
25 }
26
27 int main(void)
28 {
29 wchar_t s[128];
30 wint_t c;
31
Sample Input:
!foo#bar*baz
Sample output:
!: foo
#: bar
*: baz
See Also
fgetwc(), ungetc()
Synopsis
#include <wchar.h>
Description
These are the wide counterparts to the strtod() family of functions. See their reference pages for details.
Return Value
Returns the string converted to a floating point value.
Returns 0 if there’s no valid number in the string.
On overflow, returns an apporpriately-signed HUGE_VAL, HUGE_VALF. or HUGE_VALL depending on the return
type, and errno is set to ERANGE.
On underflow, returns a number no greater than the smallest normalized positive number, appropriately
signed. The implemention might set errno to ERANGE.
Example
1 #include <wchar.h>
2
3 int main(void)
4 {
5 wchar_t *inp = L" 123.4567beej";
6 wchar_t *badchar;
7
18 if (*badchar == L'\0')
19 wprintf(L"No bad chars: %f\n", val);
20 else
21 wprintf(L"Found bad chars: %f, %ls\n", val, badchar);
22 }
Output:
Converted string to 123.456700
Encountered bad characters: beej
Chapter 30. <wchar.h> Wide Character Handling 387
See Also
wcstol(), strtod(), errno
Synopsis
#include <wchar.h>
Description
These are the wide counterparts to the strtol() family of functions, so see their reference pages for the
details.
Return Value
Returns the integer value of the string.
If nothing can be found, 0 is returned.
If the result is out of range, the value returned is one of LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX,
ULONG_MAX or ULLONG_MAX, as appropriate. And errno is set to ERANGE.
Example
1 #include <wchar.h>
2
3 int main(void)
4 {
5 // All output in decimal (base 10)
6
16 wchar_t *badchar;
17 long int x = wcstol(L" 1234beej", &badchar, 0);
18
Output:
123
123
42
83
291
83
291
Value is 1234
Bad chars at "beej"
See Also
wcstod(), strtol(), errno, wcstoimax(), wcstoumax()
Synopsis
#include <wchar.h>
Description
These are the wide versions of strcpy() and strncpy().
They’ll copy a string up to a wide NUL. Or, in the case of the safer wcsncpy(), until then or until n wide
characters are copied.
If the string in s1 is shorter than n, wcsncpy() will pad s2 with wide NUL characters until the nth wide
character is reached.
Chapter 30. <wchar.h> Wide Character Handling 389
Even though wcsncpy() is safer because it will never overrun the end of s2 (assuming you set n correctly),
it’s still unsafe a NUL is not found in s1 in the first n characters. In that case, s2 will not be NUL-terminated.
Always make sure n is greater than the string length of s1!
Return Value
Returns s1.
Example
1 #include <wchar.h>
2
3 int main(void)
4 {
5 wchar_t *s1 = L"Hello!";
6 wchar_t s2[10];
7
See Also
wmemcpy(), wmemmove() strcpy(), strncpy()
Synopsis
#include <wchar.h>
Description
These are the wide versions of memcpy() and memmove().
They copy n wide characters from s2 to s1.
They’re the same except that wmemmove() is guaranteed to work with overlapping memory regions, and
wmemcpy() is not.
Return Value
Both functions return the pointer s1.
Chapter 30. <wchar.h> Wide Character Handling 390
Example
1 #include <wchar.h>
2
3 int main(void)
4 {
5 wchar_t s[100] = L"Goats";
6 wchar_t t[100];
7
Output:
s is "GoGoats"
t is "Goats"
See Also
wcscpy(), wcsncpy(), memcpy(), memmove()
Synopsis
#include <wchar.h>
Description
These are the wide variants of strcat() and strncat().
They concatenate s2 onto the end of s1.
They’re the same except wcsncat() gives you the option to limit the number of wide characters appended.
Note that wcsncat() always adds a NUL terminator to the end, even if n characters were appended. So be
sure to leave room for that.
Return Value
Both functions return the pointer s1.
Chapter 30. <wchar.h> Wide Character Handling 391
Example
1 #include <wchar.h>
2
3 int main(void)
4 {
5 wchar_t dest[30] = L"Hello";
6 wchar_t *src = L", World!";
7 wchar_t numbers[] = L"12345678";
8
11 wcscat(dest, src);
12 wprintf(L"dest after strcat: \"%ls\"\n", dest); // "Hello, world!"
13
See Also
strcat(), strncat()
Synopsis
#include <wchar.h>
Description
These are the wide variants of memcmp(), strcmp(), and strncmp().
wcscmp() and wcsncmp() both compare strings until a NUL character.
wcsncmp() also has the additional restriction that it will only compare the first n characters.
The comparison is done against the character value (which might (or might not) be its Unicode code point).
Return Value
Returns zero if both regions are equal.
Chapter 30. <wchar.h> Wide Character Handling 392
Example
1 #include <wchar.h>
2
3 int main(void)
4 {
5 wchar_t *s1 = L"Muffin";
6 wchar_t *s2 = L"Muffin Sandwich";
7 wchar_t *s3 = L"Muffin";
8
12 if (wcscmp(s1, s2) == 0)
13 wprintf(L"This won't get printed because the strings differ\n");
14
15 if (wcscmp(s1, s3) == 0)
16 wprintf(L"This will print because s1 and s3 are the same\n");
17
24 if (!wcscmp(s1, s3))
25 wprintf(L"The strings are the same!\n");
26
Output:
-1
1
This will print because s1 and s3 are the same
The strings are the same!
The first 6 characters of s1 and s2 are the same
See Also
wcscoll(), memcmp(), strcmp(), strncmp()
30.18 wcscoll()
Compare two wide strings accounting for locale
Chapter 30. <wchar.h> Wide Character Handling 393
Synopsis
#include <wchar.h>
Description
This is the wide version of strcoll(). See that reference page for details.
This is slower than wcscmp(), so only use it if you need the locale-specific compare.
Return Value
Returns zero if both regions are equal in this locale.
Returns a negative number if the region pointed to by s1 is less than s2 in this locale.
Returns a positive number if the region pointed to by s1 is greater than s2 in this locale.
Example
1 #include <wchar.h>
2 #include <locale.h>
3
4 int main(void)
5 {
6 setlocale(LC_ALL, "");
7
See Also
wcscmp(), wcsxfrm(), strcoll()
30.19 wcsxfrm()
Transform a wide string for comparing based on locale
Synopsis
#include <wchar.h>
Description
This is the wide variant of strxfrm(). See that reference page for details.
Return Value
Returns the length of the transformed wide string in wide characters.
If the return value is greater than n, all bets are off for the result in s1.
Example
1 #include <wchar.h>
2 #include <locale.h>
3 #include <stdlib.h>
4
12 wcsxfrm(d, s, len);
13
14 return d;
15 }
16
25 free(s1_transformed);
26
27 return result;
28 }
29
30 int main(void)
31 {
32 setlocale(LC_ALL, "");
33
42 free(s);
Chapter 30. <wchar.h> Wide Character Handling 395
43 }
Output:
1
-1
1
See Also
wcscmp(), wcscoll(), strxfrm()
Synopsis
#include <wchar.h>
Description
These are the wide equivalents to strchr(), strrchr(), and memchr().
They search for wide characters in a wide string from the front (wcschr()), the end (wcsrchr()) or for an
arbitrary number of wide characters (wmemchr()).
Return Value
All three functions return a pointer to the wide character found, or NULL if the character, sadly, isn’t found.
Example
1 #include <wchar.h>
2
3 int main(void)
4 {
5 // "Hello, world!"
6 // ^ ^ ^
7 // A B C
8
Output:
Found a 'B' here: BIG BROWN BAT BIT BEEJ
Found a 'B' here: BROWN BAT BIT BEEJ
Found a 'B' here: BAT BIT BEEJ
Found a 'B' here: BIT BEEJ
Found a 'B' here: BEEJ
See Also
strchr(), strrchr(), memchr()
Synopsis
#include <wchar.h>
Description
The are the wide character counterparts to [strspn()] (#man-strspn)and strcspn().
They compute the length of the string pointed to by s1 consisting entirely of the characters found in s2. Or,
in the case of wcscspn(), the characters not found in s2.
Return Value
The length of the string pointed to by s1 consisting solely of the characters in s2 (in the case of wcsspn())
or of the characters not in s2 (in th ecase of wcscspn()).
Chapter 30. <wchar.h> Wide Character Handling 397
Example
1 #include <wchar.h>
2
3 int main(void)
4 {
5 wchar_t str1[] = L"a banana";
6 wchar_t str2[] = L"the bolivian navy on maneuvers in the south pacific";
7 int n;
8
9 // how many letters in str1 until we reach something that's not a vowel?
10 n = wcsspn(str1, L"aeiou");
11 wprintf(L"%d\n", n); // n == 1, just "a"
12
See Also
wcschr(), wcsrchr(), strspn()
30.22 wcspbrk()
Search a wide string for one of a set of wide characters
Synopsis
#include <wchar.h>
Description
This is the wide character variant of strpbrk().
It finds the first occurrance of any of a set of wide characters in a wide string.
Return Value
Returns a pointer to the first character in the string s1 that exists in the string s2.
Or NULL if none of the characters in s2 can be found in s1.
Chapter 30. <wchar.h> Wide Character Handling 398
Example
1 #include <wchar.h>
2
3 int main(void)
4 {
5 // p points here after wcspbrk
6 // v
7 wchar_t *s1 = L"Hello, world!";
8 wchar_t *s2 = L"dow!"; // Match any of these chars
9
See Also
wcschr(), wmemchr(), strpbrk()
30.23 wcsstr()
Find a wide string in another wide string
Synopsis
#include <wchar.h>
Description
This is the wide variant of strstr().
It locates a substring in a string.
Return Value
Returns a pointer to the location in s1 that contains s2.
Or NULL if s2 cannot be found in s1.
Example
1 #include <wchar.h>
2
3 int main(void)
4 {
5 wchar_t *str = L"The quick brown fox jumped over the lazy dogs.";
6 wchar_t *p;
7
Chapter 30. <wchar.h> Wide Character Handling 399
8 p = wcsstr(str, L"lazy");
9 wprintf(L"%ls\n", p == NULL? L"null": p); // "lazy dogs."
10
See Also
wcschr(), wcsrchr(), wcsspn(), wcscspn(), strstr()
30.24 wcstok()
Tokenize a wide string
Synopsis
#include <wchar.h>
wchar_t *wcstok(wchar_t * restrict s1, const wchar_t * restrict s2,
wchar_t ** restrict ptr);
Description
This is the wide version of strtok().
And, like that one, it modifies the string s1. So make a copy of it first if you want to preserve the original.
One key difference is that wcstok() can be threadsafe because you pass in the pointer ptr to the current state
of the transformation. This gets initializers for you when s1 is initially passed in as non-NULL. (Subsequent
calls with a NULL s1 cause the state to update.)
Return Value
Example
1 #include <wchar.h>
2
3 int main(void)
4 {
5 // break up the string into a series of space or
6 // punctuation-separated words
7 wchar_t str[] = L"Where is my bacon, dude?";
8 wchar_t *token;
9 wchar_t *state;
10
16 do {
17 wprintf(L"Word: \"%ls\"\n", token);
18
Output:
Word: "Where"
Word: "is"
Word: "my"
Word: "bacon"
Word: "dude"
See Also
strtok()
30.25 wcslen()
Returns the length of a wide string
Synopsis
#include <wchar.h>
Description
This is the wide counterpart to strlen().
Return Value
Returns the number of wide characters before the wide NUL terminator.
Example
1 #include <wchar.h>
2
3 int main(void)
4 {
5 wchar_t *s = L"Hello, world!"; // 13 characters
6
See Also
strlen()
30.26 wcsftime()
Formatted date and time output
Synopsis
#include <time.h>
#include <wchar.h>
Description
This is the wide equivalent to strftime(). See that reference page for details.
maxsize here refers to the maximum number of wide characters that can be in the result string.
Return Value
If successful, returns the number of wide characters written.
If not successful because the result couldn’t fit in the space alloted, 0 is returned and the contents of the string
could be anything.
Example
1 #include <wchar.h>
2 #include <time.h>
3
6 int main(void)
7 {
8 wchar_t s[BUFSIZE];
9 time_t now = time(NULL);
10
See Also
strftime()
Synopsis
#include <wchar.h>
Description
These functions convert between single byte characters and wide characters, and vice-versa.
Even though ints are involved, don’t let this mislead you; they’re effectively converted to unsigned chars
internally.
The characters in the basic character set are guaranteed to be a single byte.
Return Value
btowc() returns the single-byte character as a wide character. Returns WEOF if EOF is passed in, or if the
byte doesn’t correspond to a valid wide character.
wctob() returns the wide character as a single-byte character. Returns EOF if WEOF is passed in, or if the
wide character doesn’t correspond to a value single-byte character.
See mbtowc() and wctomb() for multibyte to wide character conversion.
Chapter 30. <wchar.h> Wide Character Handling 403
Example
1 #include <wchar.h>
2
3 int main(void)
4 {
5 wint_t wc = btowc('B'); // Convert single byte to wide char
6
Output:
Wide character: B
Single-byte character: B
See Also
mbtowc(), wctomb()
30.28 mbsinit()
Test if an mbstate_t is in the initial conversion state
Synopsis
#include <wchar.h>
Description
For a given conversion state in a mbstate_t variable, this function determines if it’s in the initial conversion
state.
Return Value
Returns non-zero if the value pointed to by ps is in the initial conversion state, or if ps is NULL.
Returns 0 if the value pointed to by ps is not in the initial conversion state.
Example
For me, this example doesn’t do anything exciting, saying that the mbstate_t variable is always in the initial
state. Yay.
But if have a stateful encoding like 2022-JP, try messing around with this to see if you can get into an
intermediate state.
Chapter 30. <wchar.h> Wide Character Handling 404
This program has a bit of code at the top that reports if your locale’s encoding requires any state.
1 #include <locale.h> // For setlocale()
2 #include <string.h> // For memset()
3 #include <stdlib.h> // For mbtowc()
4 #include <wchar.h>
5
6 int main(void)
7 {
8 mbstate_t state;
9 wchar_t wc[128];
10
11 setlocale(LC_ALL, "");
12
See Also
mbtowc(), wctomb(), mbrtowc(), wcrtomb()
30.29 mbrlen()
Compute the number of bytes in a multibyte character, restartably
Synopsis
#include <wchar.h>
Description
This is the restartable version of mblen().
It inspects at most n bytes of the string s to see how many bytes in this character.
The conversion state is stored in ps.
This function doesn’t have the functionality of mblen() that allowed you to query if this character encoding
was stateful and to reset the internal state.
Chapter 30. <wchar.h> Wide Character Handling 405
Return Value
Returns the number of bytes required for this multibyte character.
Returns (size_t)(-1) if the data in s is not a valid multibyte character.
Returns (size_t)(-2) if the data is s is a valid but not complete multibyte character.
Example
If your character set doesn’t support the Euro symbol “€”, substitute the Unicode escape sequence \u20ac,
below.
1 #include <locale.h> // For setlocale()
2 #include <string.h> // For memset()
3 #include <wchar.h>
4
5 int main(void)
6 {
7 mbstate_t state;
8 int len;
9
10 setlocale(LC_ALL, "");
11
Output:
Length of 'B' is 1 byte(s)
Length of '€' is 3 byte(s)
See Also
mblen()
30.30 mbrtowc()
Convert multibyte to wide characters restartably
Synopsis
#include <wchar.h>
Description
This is the restartable counterpart to mbtowc().
It converts individual characters from multibyte to wide, tracking the conversion state in the variable pointed
to by ps.
At most n bytes are inspected for conversion to a wide character.
These two variants are identical and cause the state pointed to by ps to be set to the initial conversion state:
mbrtowc(NULL, NULL, 0, &state);
mbrtowc(NULL, "", 1, &state);
Also, if you’re just interested in the length in bytes of the multibyte character, you can pass NULL for pwc and
nothing will be stored for the wide character:
int len = mbrtowc(NULL, "€", 5, &state);
This function doesn’t have the functionality of mbtowc() that allowed you to query if this character encoding
was stateful and to reset the internal state.
Return Value
On success, returns a positive number corresponding to the number of bytes in the multibyte character.
Returns 0 if the character encoded is a wide NUL character.
Returns (size_t)(-1) if the data in s is not a valid multibyte character.
Returns (size_t)(-2) if the data is s is a valid but not complete multibyte character.
Example
If your character set doesn’t support the Euro symbol “€”, substitute the Unicode escape sequence \u20ac,
below.
1 #include <string.h> // For memset()
2 #include <stdlib.h> // For mbtowc()
3 #include <locale.h> // For setlocale()
4 #include <wchar.h>
5
6 int main(void)
7 {
8 mbstate_t state;
9
12 setlocale(LC_ALL, "");
13
16 wchar_t wc;
17 int bytes;
18
Output on my system:
State dependency: 0
L'€' takes 3 bytes as multibyte char '€'
See Also
mbtowc(), wcrtomb()
30.31 wcrtomb()
Convert wide to multibyte characters restartably
Synopsis
#include <wchar.h>
Description
This is the restartable counterpart to wctomb().
It converts individual characters from wide to multibyte, tracking the conversion state in the variable pointed
to by ps.
The destination array s should be at least MB_CUR_MAX2 bytes in size—you won’t get anything bigger back
from this function.
Note that the values in this result array won’t be NUL-terminated.
If you pass a wide NUL character in, the result will contain any bytes needed to restore the conversion state
to its initial state followed by a NUL character, and the state pointed to by ps will be reset to its initial state:
// Reset state
wcrtomb(mb, L'\0', &state)
If you don’t care about the results (i.e. you’re just interested in resetting the state or getting the return value),
you can do this by passing NULL for s:
wcrtomb(NULL, L'\0', &state); // Reset state
This function doesn’t have the functionality of wctomb() that allowed you to query if this character encoding
was stateful and to reset the internal state.
Return Value
On success, returns the number of bytes needed to encode this wide character in the current locale.
If the input is an invalid wide character, errno will be set to EILSEQ and the function returns (size_t)(-1).
If this happens, all bets are off for the conversion state, so you might as well reset it.
2
This is a variable, not a macro, so if you use it to define an array, it’ll be a variable-length array.
Chapter 30. <wchar.h> Wide Character Handling 408
Example
If your character set doesn’t support the Euro symbol “€”, substitute the Unicode escape sequence \u20ac,
below.
1 #include <string.h> // For memset()
2 #include <stdlib.h> // For mbtowc()
3 #include <locale.h> // For setlocale()
4 #include <wchar.h>
5
6 int main(void)
7 {
8 mbstate_t state;
9
12 setlocale(LC_ALL, "");
13
See Also
mbrtowc(), wctomb(), errno
30.32 mbsrtowcs()
Convert a multibyte string to a wide character string restartably
Synopsis
#include <wchar.h>
Description
This is the restartable version of mbstowcs().
It converts a multibyte string to a wide character string.
The result is put in the buffer pointed to by dst, and the pointer src is updated to indicate how much of the
string was consumed (unless dst is NULL).
At most len wide characters will be stored.
This also takes a pointer to its own mbstate_t variable in ps for holding the conversion state.
Chapter 30. <wchar.h> Wide Character Handling 409
You can set dst to NULL if you only care about the return value. This could be useful for getting the number
of characters in a multibyte string.
In the normal case, the src string will be consumed up to the NUL character, and the results will be stored
in the dst buffer, including the wide NUL character. In this case, the pointer pointed to by src will be set
to NULL. And the conversion state will be set to the initial conversion state.
If things go wrong because the source string isn’t a valid sequence of characters, conversion will stop and
the pointer pointed to by src will be set to the address just after the last successfully-translated multibyte
character.
Return Value
If successful, returns the number of characters converted, not including any NUL terminator.
If the multibyte sequence is invalid, the function returns (size_t)(-1) and errno is set to EILSEQ.
Example
Here we’ll convert the string “€5 ± π” into a wide character string:
1 #include <locale.h> // For setlocale()
2 #include <string.h> // For memset()
3 #include <wchar.h>
4
5 #define WIDE_STR_SIZE 10
6
7 int main(void)
8 {
9 const char *mbs = "€5 ± π"; // That's the exact price range
10
11 wchar_t wcs[WIDE_STR_SIZE];
12
13 setlocale(LC_ALL, "");
14
15 mbstate_t state;
16 memset(&state, 0, sizeof state);
17
Output:
Wide string L"€5 ± π" is 6 characters
Here’s another example of using mbsrtowcs() to get the length in characters of a multibyte string even if
the string is full of multibyte characters. This is in contrast to strlen(), which returns the total number of
bytes in the string.
1 #include <stdio.h> // For printf()
2 #include <locale.h> // For setlocale()
3
17 int main(void)
18 {
19 setlocale(LC_ALL, "");
20
Output on my system:
"€5 ± π" is 6 characters...
but it's 10 bytes!
See Also
mbrtowc(), mbstowcs(), wcsrtombs(), strlen(), errno
30.33 wcsrtombs()
Convert a wide character string to a multibyte string restartably
Synopsis
#include <wchar.h>
Description
If you have a wide character string, you can convert it to a multibyte character string in the current locale
using this function.
At most len bytes of data will be stored in the buffer pointed to by dst. Conversion will stop just after the
NUL terminator is copied, or len bytes get copied, or some other error occurs.
If dst is a NULL pointer, no result is stored. You might do this if you’re just interested in the return value
(nominally the number of bytes this would use in a multibyte string, not including the NUL terminator).
If dst is not a NULL pointer, the pointer pointed to by src will get modified to indicate how much of the data
was copied. If it contains NULL at the end, it means everything went well. In this case, the state ps will be
set to the initial conversion state.
Chapter 30. <wchar.h> Wide Character Handling 411
If len was reached or an error occurred, it’ll point one address past dst+len.
Return Value
If everything goes well, returns the number of bytes needed for the multibyte string, not counting the NUL
terminator.
If any character in the string doesn’t correspond to a valid multibyte character in the currently locale, it returns
(size_t)(-1) and EILSEQ is stored in errno.
Example
Here we’ll convert the wide string “€5 ± π” into a multibyte character string:
1 #include <locale.h> // For setlocale()
2 #include <string.h> // For memset()
3 #include <wchar.h>
4
5 #define MB_STR_SIZE 20
6
7 int main(void)
8 {
9 const wchar_t *wcs = L"€5 ± π"; // That's the exact price range
10
11 char mbs[MB_STR_SIZE];
12
13 setlocale(LC_ALL, "");
14
15 mbstate_t state;
16 memset(&state, 0, sizeof state);
17
Here’s another example helper function that malloc()s just enough memory to hold the converted string,
then returns the result. (Which must later be freed, of course, to prevent leaking memory.)
1 #include <stdlib.h> // For malloc()
2 #include <locale.h> // For setlocale()
3 #include <string.h> // For memset()
4 #include <stdint.h> // For SIZE_MAX
5 #include <wchar.h>
6
11 mbstate_t state;
12 memset(&state, 0, sizeof state);
13
39 // Success!
40 return mbs;
41 }
42
43 int main(void)
44 {
45 char *mbs = get_mb_string(L"€5 ± π");
46
49 free(mbs);
50 }
See Also
wcrtomb(), wcstombs(), mbsrtowcs(), errno
Chapter 31
Function Description
iswalnum() Test if a wide character is alphanumeric.
iswalpha() Tests if a wide character is alphabetic
iswblank() Tests if this is a wide blank character
iswcntrl() Tests if this is a wide control character.
iswctype() Determine wide character classification
iswdigit() Test if this wide character is a digit
iswgraph() Test to see if a wide character is a printable non-space
iswlower() Tests if a wide character is lowercase
iswprint() Tests if a wide character is printable
iswpunct() Test if a wide character is punctuation
iswspace() Test if a wide character is whitespace
iswupper() Tests if a wide character is uppercase
iswxdigit() Tests if a wide character is a hexadecimal digit
towctrans() Convert wide characters to upper or lowercase
towlower() Convert an uppercase wide character to lowercase
towupper() Convert a lowercase wide character to uppercase
wctrans() Helper function for towctrans()
wctype() Helper function for iswctype()
31.1 iswalnum()
Test if a wide character is alphanumeric.
413
Chapter 31. <wctype.h> Wide Character Classification and Transformation 414
Synopsis
#include <wctype.h>
Description
Basically tests if a character is alphabetic (A-Z or a-z) or a digit (0-9). But some other characters might also
qualify based on the locale.
This is equivalent to testing if iswalpha() or iswdigit() is true.
Return Value
Returns true if the character is alphanumeric.
Example
1 #include <wchar.h>
2 #include <wctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 wprintf(L"%ls\n", iswalnum(L'a')? L"yes": L"no"); // yes
9 wprintf(L"%ls\n", iswalnum(L'B')? L"yes": L"no"); // yes
10 wprintf(L"%ls\n", iswalnum(L'5')? L"yes": L"no"); // yes
11 wprintf(L"%ls\n", iswalnum(L'?')? L"yes": L"no"); // no
12 }
See Also
iswalpha(), iswdigit(), isalnum()
31.2 iswalpha()
Tests if a wide character is alphabetic
Synopsis
#include <wctype.h>
Description
Basically tests if a character is alphabetic (A-Z or a-z). But some other characters might also qualify based
on the locale. (If other characters qualify, they won’t be control characters, digits, punctuation, or spaces.)
This is the same as testing for iswupper() or iswlower().
Chapter 31. <wctype.h> Wide Character Classification and Transformation 415
Return Value
Returns true if the character is alphabetic.
Example
1 #include <wchar.h>
2 #include <wctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 wprintf(L"%ls\n", iswalpha(L'a')? L"yes": L"no"); // yes
9 wprintf(L"%ls\n", iswalpha(L'B')? L"yes": L"no"); // yes
10 wprintf(L"%ls\n", iswalpha(L'5')? L"yes": L"no"); // no
11 wprintf(L"%ls\n", iswalpha(L'?')? L"yes": L"no"); // no
12 }
See Also
iswalnum(), isalpha()
31.3 iswblank()
Tests if this is a wide blank character
Synopsis
#include <wctype.h>
Description
Blank characters are whitespace that are also used as word separators on the same line. In the “C” locale, the
only blank characters are space and tab.
Other locales might define other blank characters.
Return Value
Returns true if this is a blank character.
Example
1 #include <wchar.h>
2 #include <wctype.h>
3
4 int main(void)
5 {
Chapter 31. <wctype.h> Wide Character Classification and Transformation 416
See Also
iswspace(), isblank()
31.4 iswcntrl()
Tests if this is a wide control character.
Synopsis
#include <wctype.h>
Description
The spec is pretty barren, here. But I’m just going to assume that it works like the non-wide version. So let’s
look at that.
A control character is a locale-specific non-printing character.
For the “C” locale, this means control characters are in the range 0x00 to 0x1F (the character right before
SPACE) and 0x7F (the DEL character).
Basically if it’s not an ASCII (or Unicode less than 128) printable character, it’s a control character in the
“C” locale.
Probably.
Return Value
Returns true if this is a control character.
Example
1 #include <wchar.h>
2 #include <wctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 wprintf(L"%ls\n", iswcntrl(L'\t')? L"yes": L"no"); // yes (tab)
Chapter 31. <wctype.h> Wide Character Classification and Transformation 417
See Also
iscntrl()
31.5 iswdigit()
Test if this wide character is a digit
Synopsis
#include <wctype.h>
Description
Tests if the wide character is a digit (0-9).
Return Value
Returns true if the character is a digit.
Example
1 #include <wchar.h>
2 #include <wctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 wprintf(L"%ls\n", iswdigit(L'0')? L"yes": L"no"); // yes
9 wprintf(L"%ls\n", iswdigit(L'5')? L"yes": L"no"); // yes
10 wprintf(L"%ls\n", iswdigit(L'a')? L"yes": L"no"); // no
11 wprintf(L"%ls\n", iswdigit(L'B')? L"yes": L"no"); // no
12 wprintf(L"%ls\n", iswdigit(L'?')? L"yes": L"no"); // no
13 }
See Also
iswalnum(), isdigit()
Chapter 31. <wctype.h> Wide Character Classification and Transformation 418
31.6 iswgraph()
Test to see if a wide character is a printable non-space
Synopsis
#include <wctype.h>
Description
Returns true if this is a printable (non-control) character and also not a whitespace character.
Basically if iswprint() is true and iswspace() is false.
Return Value
Returns true if this is a printable non-space character.
Example
1 #include <wchar.h>
2 #include <wctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 wprintf(L"%ls\n", iswgraph(L'0')? L"yes": L"no"); // yes
9 wprintf(L"%ls\n", iswgraph(L'a')? L"yes": L"no"); // yes
10 wprintf(L"%ls\n", iswgraph(L'B')? L"yes": L"no"); // yes
11 wprintf(L"%ls\n", iswgraph(L'?')? L"yes": L"no"); // yes
12 wprintf(L"%ls\n", iswgraph(L' ')? L"yes": L"no"); // no
13 wprintf(L"%ls\n", iswgraph(L'\n')? L"yes": L"no"); // no
14 }
See Also
iswprint(), iswspace(), isgraph()
31.7 iswlower()
Tests if a wide character is lowercase
Synopsis
#include <wctype.h>
Description
Tests if a character is lowercase, in the range a-z.
In other locales, there could be other lowercase characters. In all cases, to be lowercase, the following must
be true:
!iswcntrl(c) && !iswdigit(c) && !iswpunct(c) && !iswspace(c)
Return Value
Returns true if the wide character is lowercase.
Example
1 #include <wchar.h>
2 #include <wctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 wprintf(L"%ls\n", iswlower(L'c')? L"yes": L"no"); // yes
9 wprintf(L"%ls\n", iswlower(L'0')? L"yes": L"no"); // no
10 wprintf(L"%ls\n", iswlower(L'B')? L"yes": L"no"); // no
11 wprintf(L"%ls\n", iswlower(L'?')? L"yes": L"no"); // no
12 wprintf(L"%ls\n", iswlower(L' ')? L"yes": L"no"); // no
13 }
See Also
islower(), iswupper(), iswalpha(), towupper(), towlower()
31.8 iswprint()
Tests if a wide character is printable
Synopsis
#include <wctype.h>
Description
Tests if a wide character is printable, including space (' '). So like isgraph(), except space isn’t left out
in the cold.
Return Value
Returns true if the wide character is printable, including space (' ').
Chapter 31. <wctype.h> Wide Character Classification and Transformation 420
Example
1 #include <wchar.h>
2 #include <wctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 wprintf(L"%ls\n", iswprint(L'c')? L"yes": L"no"); // yes
9 wprintf(L"%ls\n", iswprint(L'0')? L"yes": L"no"); // yes
10 wprintf(L"%ls\n", iswprint(L' ')? L"yes": L"no"); // yes
11 wprintf(L"%ls\n", iswprint(L'\r')? L"yes": L"no"); // no
12 }
See Also
isprint(), iswgraph(), iswcntrl()
31.9 iswpunct()
Test if a wide character is punctuation
Synopsis
#include <wctype.h>
Description
Tests if a wide character is punctuation.
This means for any given locale:
!isspace(c) && !isalnum(c)
Return Value
True if the wide character is punctuation.
Example
Results may vary based on locale.
1 #include <wchar.h>
2 #include <wctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
Chapter 31. <wctype.h> Wide Character Classification and Transformation 421
See Also
ispunct(), iswspace(), iswalnum()
31.10 iswspace()
Test if a wide character is whitespace
Synopsis
#include <wctype.h>
Description
Tests if c is a whitespace character. These are probably:
• Space (' ')
• Formfeed ('\f')
• Newline ('\n')
• Carriage Return ('\r')
• Horizontal Tab ('\t')
• Vertical Tab ('\v')
Other locales might specify other whitespace characters. iswalnum(), iswgraph(), and iswpunct() are
all false for all whitespace characters.
Return Value
True if the character is whitespace.
Example
Results may vary based on locale.
1 #include <wchar.h>
2 #include <wctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 wprintf(L"%ls\n", iswspace(L' ')? L"yes": L"no"); // yes
Chapter 31. <wctype.h> Wide Character Classification and Transformation 422
See Also
isspace(), iswblank()
31.11 iswupper()
Tests if a wide character is uppercase
Synopsis
#include <wctype.h>
Description
Tests if a character is uppercase in the current locale.
To be uppercase, the following must be true:
!iscntrl(c) && !isdigit(c) && !ispunct(c) && !isspace(c)
Return Value
Returns true if the wide character is uppercase.
Example
1 #include <wchar.h>
2 #include <wctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 wprintf(L"%ls\n", iswupper(L'B')? L"yes": L"no"); // yes
9 wprintf(L"%ls\n", iswupper(L'c')? L"yes": L"no"); // no
10 wprintf(L"%ls\n", iswupper(L'0')? L"yes": L"no"); // no
11 wprintf(L"%ls\n", iswupper(L'?')? L"yes": L"no"); // no
12 wprintf(L"%ls\n", iswupper(L' ')? L"yes": L"no"); // no
13 }
Chapter 31. <wctype.h> Wide Character Classification and Transformation 423
See Also
isupper(), iswlower(), iswalpha(), towupper(), towlower()
31.12 iswxdigit()
Tests if a wide character is a hexadecimal digit
Synopsis
#include <wctype.h>
Description
Returns true if the wide character is a hexadecimal digit. Namely if it’s 0-9, a-f, or A-F.
Return Value
True if the character is a hexadecimal digit.
Example
1 #include <wchar.h>
2 #include <wctype.h>
3
4 int main(void)
5 {
6 // testing this char
7 // v
8 wprintf(L"%ls\n", iswxdigit(L'B')? L"yes": L"no"); // yes
9 wprintf(L"%ls\n", iswxdigit(L'c')? L"yes": L"no"); // yes
10 wprintf(L"%ls\n", iswxdigit(L'2')? L"yes": L"no"); // yes
11 wprintf(L"%ls\n", iswxdigit(L'G')? L"yes": L"no"); // no
12 wprintf(L"%ls\n", iswxdigit(L'?')? L"yes": L"no"); // no
13 }
See Also
isxdigit(), iswdigit()
31.13 iswctype()
Determine wide character classification
Chapter 31. <wctype.h> Wide Character Classification and Transformation 424
Synopsis
#include <wctype.h>
Description
This is the Swiss Army knife of classification functions; it’s all the other ones rolled into one.
You call it with something like this:
if (iswctype(c, wctype("digit"))) // or "alpha" or "space" or...
The difference is that you can specify the type of matching you want to do as a string at runtime, which might
be convenient.
iswctype() relies on the return value from the wctype() call to get its work done.
Stolen from the spec, here are the iswctype() calls and their equivalents:
See the wctype() documentation for how that helper function works.
Return Value
Returns true if the wide character wc matches the character class in desc.
Example
Test for a given character classification at when the classification isn’t known at compile time:
1 #include <stdio.h> // for fflush(stdout)
2 #include <wchar.h>
3 #include <wctype.h>
4
5 int main(void)
6 {
7 wchar_t c; // Holds a single wide character (to test)
Chapter 31. <wctype.h> Wide Character Classification and Transformation 425
18 if (t == 0)
19 // If the type is 0, it's an unknown class
20 wprintf(L"Unknown character class: \"%s\"\n", desc);
21 else {
22 // Otherwise, let's test the character and see if its that
23 // classification
24 if (iswctype(c, t))
25 wprintf(L"Yes! '%lc' is %s!\n", c, desc);
26 else
27 wprintf(L"Nope! '%lc' is not %s.\n", c, desc);
28 }
29 }
Output:
Enter a character and character class: 5 digit
Yes! '5' is digit!
See Also
wctype()
31.14 wctype()
Helper function for iswctype()
Synopsis
#include <wctype.h>
Description
This function returns an opaque value for the given property that is meant to be passed as the second
argument to iswctype().
Chapter 31. <wctype.h> Wide Character Classification and Transformation 426
Other properties might be defined as determined by the LC_CTYPE category of the current locale.
See the iswctype() reference page for more usage details.
Return Value
Returns the wctype_t value associated with the given property.
If an invalid value is passed for property, returns 0.
Example
Test for a given character classification at when the classification isn’t known at compile time:
1 #include <stdio.h> // for fflush(stdout)
2 #include <wchar.h>
3 #include <wctype.h>
4
5 int main(void)
6 {
7 wchar_t c; // Holds a single wide character (to test)
8 char desc[128]; // Holds the character class
9
18 if (t == 0)
19 // If the type is 0, it's an unknown class
20 wprintf(L"Unknown character class: \"%s\"\n", desc);
21 else {
22 // Otherwise, let's test the character and see if its that
23 // classification
24 if (iswctype(c, t))
25 wprintf(L"Yes! '%lc' is %s!\n", c, desc);
26 else
27 wprintf(L"Nope! '%lc' is not %s.\n", c, desc);
28 }
29 }
Output:
Enter a character and character class: 5 digit
Yes! '5' is digit!
See Also
iswctype()
31.15 towlower()
Convert an uppercase wide character to lowercase
Synopsis
#include <wctype.h>
Description
If the character is upper (i.e. iswupper(c) is true), this function returns the corresponding lowercase letter.
Different locales might have different upper and lowercase letters.
Return Value
If the letter wc is uppercase, a lowercase version of that letter will be returned according to the current locale.
If the letter is not uppercase, wc is returned unchanged.
Example
1 #include <wchar.h>
2 #include <wctype.h>
3
4 int main(void)
5 {
6 // changing this char
7 // v
8 wprintf(L"%lc\n", towlower(L'B')); // b (made lowercase!)
9 wprintf(L"%lc\n", towlower(L'e')); // e (unchanged)
10 wprintf(L"%lc\n", towlower(L'!')); // ! (unchanged)
11 }
See Also
tolower(), towupper(), iswlower(), iswupper()
Chapter 31. <wctype.h> Wide Character Classification and Transformation 428
31.16 towupper()
Convert a lowercase wide character to uppercase
Synopsis
#include <wctype.h>
Description
If the character is lower (i.e. iswlower(c) is true), this function returns the corresponding uppercase letter.
Different locales might have different upper and lowercase letters.
Return Value
If the letter wc is lowercase, an uppercase version of that letter will be returned according to the current locale.
If the letter is not lowercase, wc is returned unchanged.
Example
1 #include <wchar.h>
2 #include <wctype.h>
3
4 int main(void)
5 {
6 // changing this char
7 // v
8 wprintf(L"%lc\n", towupper(L'B')); // B (unchanged)
9 wprintf(L"%lc\n", towupper(L'e')); // E (made uppercase!)
10 wprintf(L"%lc\n", towupper(L'!')); // ! (unchanged)
11 }
See Also
toupper(), towlower(), iswlower(), iswupper()
31.17 towctrans()
Convert wide characters to upper or lowercase
Synopsis
#include <wctype.h>
Description
This is the Swiss Army knife of character conversion functions; it’s all the other ones rolled into one. And
by “all the other ones” I mean towupper() and towlower(), since those are the only ones there are.
You call it with something like this:
if (towctrans(c, wctrans("toupper"))) // or "tolower"
The difference is that you can specify the type of conversion you want to do as a string at runtime, which
might be convenient.
towctrans() relies on the return value from the wctrans() call to get its work done.
See the wctrans() documentation for how that helper function works.
Return Value
Returns the character wc as if run through towupper() or towlower(), depending on the value of desc.
If the character already matches the classification, it is returned as-is.
Example
1 #include <stdio.h> // for fflush(stdout)
2 #include <wchar.h>
3 #include <wctype.h>
4
5 int main(void)
6 {
7 wchar_t c; // Holds a single wide character (to test)
8 char desc[128]; // Holds the conversion type
9
18 if (t == 0)
19 // If the type is 0, it's an unknown conversion type
20 wprintf(L"Unknown conversion: \"%s\"\n", desc);
21 else {
22 // Otherwise, let's do the conversion
23 wint_t result = towctrans(c, t);
24 wprintf(L"'%lc' -> %s -> '%lc'\n", c, desc, result);
Chapter 31. <wctype.h> Wide Character Classification and Transformation 430
25 }
26 }
Output on my system:
Enter a character and conversion type: b toupper
'b' -> toupper -> 'B'
See Also
wctrans(), towupper(), towlower()
31.18 wctrans()
Helper function for towctrans()
Synopsis
#include <wctype.h>
Description
This is a helper function for generating the second argument to towctrans().
You can pass in one of two things for the property:
• toupper to make towctrans() behave like towupper()
• tolower to make towctrans() behave like towlower()
Return Value
On success, returns a value that can be used as the desc argument to towctrans().
Otherwise, if the property isn’t recognized, returns 0.
Example
1 #include <stdio.h> // for fflush(stdout)
2 #include <wchar.h>
3 #include <wctype.h>
4
Chapter 31. <wctype.h> Wide Character Classification and Transformation 431
5 int main(void)
6 {
7 wchar_t c; // Holds a single wide character (to test)
8 char desc[128]; // Holds the conversion type
9
18 if (t == 0)
19 // If the type is 0, it's an unknown conversion type
20 wprintf(L"Unknown conversion: \"%s\"\n", desc);
21 else {
22 // Otherwise, let's do the conversion
23 wint_t result = towctrans(c, t);
24 wprintf(L"'%lc' -> %s -> '%lc'\n", c, desc, result);
25 }
26 }
Output on my system:
Enter a character and conversion type: b toupper
'b' -> toupper -> 'B'
See Also
towctrans()
Index
432
INDEX 433
xor macro, 88
xor_eq macro, 88