strtoul(3)
๐ strtoul(3) โ the "string to unsigned long int" glow-up ๐
okay bestie, so this page lives in the Library Functions Manual, and honestly? it's giving "I convert your text into numbers and I do NOT miss." let's get into it ๐ซถ
โจ NAME โจ
strtoul, strtoull, strtouq โ string to unsigned long int, aka the trio that turns your cute little character strings into big unsigned numbers ๐
๐ LIBRARY ๐
Standard C library... which is libc, and you link it with -lc. iconic, we love a foundational queen ๐
๐ธ SYNOPSIS ๐ธ
#include <stdlib.h>
unsigned long strtoul(const char *restrict nptr,
char **_Nullable restrict endptr, int base);
unsigned long long strtoull(const char *restrict nptr,
char **_Nullable restrict endptr, int base);
๐ง Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
strtoull():
_ISOC99_SOURCE
|| /* glibc <= 2.19: */ _SVID_SOURCE || _BSD_SOURCE
ngl the whole "define a macro before you get the function" thing is so glibc-coded._ISOC99_SOURCEis your main character here, and if you're onglibc <= 2.19you can also slide in with_SVID_SOURCEor_BSD_SOURCE. periodt.
๐ซ DESCRIPTION ๐ซ
So strtoul() takes the initial part of the string sitting in nptr and converts it into an unsigned long value, according to the base you hand it. that base has to be between 2 and 36 inclusive, OR it can be the special value 0. no in-between "3.5" nonsense, bestie ๐
Here's the vibe of what the string is allowed to look like: it may start with an arbitrary amount of white space (as determined by isspace(3)), and then a single optional '+' or '-' sign. very demure. very mindful.
Now for the base detective work, and this part is important so pay attention ๐ญ:
- if
baseis zero or 16, the string may then include a"0x"or"0X"prefix, and the number will be read in base 16 ๐ฅ - if
baseis zero or 2, the string may then include a"0b"or"0B"prefix, and the number will be read in base 2 ๐ฆ - otherwise, a zero base is taken as 10 (decimal) unless the next character is
'0', in which case it is taken as 8 (octal) ๐
The rest of the string gets converted to an unsigned long value "in the obvious manner" (their words, and honestly? fair), and it stops at the first character which is not a valid digit in the given base. for bases above 10, the letter 'A' in either uppercase or lowercase represents 10, 'B' represents 11, and so on and so forth, with 'Z' representing 35. that's the whole alphabet being drafted into number duty, we love range ๐
Now, the endptr tea โ โ if endptr is not NULL, and the base is supported, strtoul() stores the address of the first invalid character in *endptr. but if there were no digits at all, strtoul() stores the original value of nptr in *endptr (and returns 0). and here's the little gotcha to remember: in particular, if *nptr is not '\0' but **endptr is '\0' on return, then the entire string is valid. chef's kiss ๐
And strtoull()? it works just like strtoul() but returns an unsigned long long value. same energy, bigger number. ๐
๐ฅ RETURN VALUE ๐ฅ
strtoul() returns either the result of the conversion, OR โ if there was a leading minus sign โ the negation of the result of the conversion represented as an unsigned value. the exception (and there's always an exception, sigh): unless the original (nonnegated) value would overflow, and in that case strtoul() returns ULONG_MAX and sets errno to ERANGE. ๐ญ
Precisely the same holds for strtoull() โ just with ULLONG_MAX instead of ULONG_MAX. ๐
๐ ERRORS ๐
- This function does not modify
errnoon success. so if you see a change in there, something else did it, bestie, don't blame us โจ EINVAL(not in C99) โ the givenbasecontains an unsupported value.ERANGEโ the resulting value was out of range.- The implementation may also set
errnotoEINVALin case no conversion was performed (no digits seen, and 0 returned). ๐
๐ ATTRIBUTES ๐
For an explanation of the terms used in this section, see attributes(7). (the original lays this out as a whole table, but here it is in bullet form so it's easier on your eyes, bestie ๐ซถ)
strtoul(),strtoull(),strtouq()โ Thread safety:MT-Safe locale๐
๐ฆ VERSIONS ๐ฆ
In locales other than the "C" locale, other strings may be accepted. for example, the thousands separator of the current locale may be supported. so yes, your locale can lowkey change what counts as a valid number. wild, I know ๐
BSD also has:
u_quad_t strtouq(const char *nptr, char **endptr, int base);
with a completely analogous definition. depending on the wordsize of the current architecture, this may be equivalent to strtoull() or to strtoul(). so it's giving "who am I today? depends on the architecture" ๐ง
โญ STANDARDS โญ
C23, POSIX.1-2024. certified, stamped, approved ๐
๐ HISTORY ๐
strtoul()โ POSIX.1-2001, C89, SVr4.strtoull()โ POSIX.1-2001, C99."0b","0B"โ C23. glibc 2.38. (Not in POSIX.)
๐ธ CAVEATS ๐ธ
okay this one's the classic trap and I need you to hear me ๐ญ since strtoul() can legitimately return 0 or ULONG_MAX (ULLONG_MAX for strtoull()) on both success and failure, the calling program should set errno to 0 before the call, and then determine if an error occurred by checking whether errno has a nonzero value after the call. don't skip the pre-call reset, bestie, it's literally the whole plot ๐ซถ
โ ๏ธ BUGS โ ๏ธ
๐ Signed numbers
Some negative values are considered valid input and are silently converted to unsigned long. silently! no warning, no drama, just vibes ๐ญ
๐ White space
These functions silently accept leading whitespace. yep. more silent behavior. ๐
๐ isalnum(3)
To reject white space and/or a sign, call isalnum(3) before strtoul(). that's the move ๐
๐ EXAMPLES ๐
See the example on the strtol(3) manual page โ the use of the functions described in this manual page is similar. go peek, bestie, it's the same energy ๐
๐ SEE ALSO ๐
a64l(3), atof(3), atoi(3), atol(3), strtod(3), strtol(3), strtoumax(3)
and that's the whole page, no cap ๐ this absolute icon of a man page comes to you from Linux man-pages 6.20, dated 2026-07-26 โ stan a consistent release schedule, periodt โจ๐ซถ
๐ฆ where this page comes from
- arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- ๐ the page's license: Linux-man-pages-copyleft
- Copyright 1993, David Metcalfe <david@prism.demon.co.uk>
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms