strtou(3bsd)

πŸ“¦
version 0.12.2 Β· 3 versions
, in alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, debian trixie, epel 10, epel 9, fedora 43, fedora 44, nixos 26.05, nixpkgs unstable, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ’– strtou β€” the manual, but make it make sense πŸ’–

okay bestie, gather round, because we're talking about strtou(3bsd) β€” a lil' LOCAL manual page from the BSD-verse that is genuinely one of the most considerate little functions you'll ever meet. no cap. it takes a string and turns it into a number, but like… safely, and it tells you when things went sideways instead of making you go spelunking through errno. we love a communicative king. πŸ‘‘


✨ NAME ✨

strtou β€” convert a string value to an uintmax_t integer

πŸ“š LIBRARY πŸ“š

Utility functions from BSD systems (libbsd, -lbsd)

🫢 SYNOPSIS 🫢

#include <inttypes.h>
(See libbsd(7) for include usage.)

uintmax_t
strtou(const char * restrict nptr, char ** restrict endptr, int base,
    uintmax_t lo, uintmax_t hi, int *rstatus);
psst β€” you gotta peek at libbsd(7) for the whole include-usage situation. it's giving "read the fine print, bestie". πŸ“–

🌸 DESCRIPTION 🌸

So here's the tea. strtou() takes the string hanging out in nptr and converts it into an uintmax_t value. Internally it's using strtoumax(3) (iconic behavior, standing on the shoulders of giants), and it makes sure the result always lands inside the range [ lo .. hi ]. like, always. no escape. πŸŽ€

And here's the part that makes it the main character: it always drops a 0 on success, or a conversion status, into the rstatus argument. which means you never have to do the whole errno gymnastics that the other conversion functions make you do. the rstatus argument can be NULL if you genuinely do not care about the conversion status. (valid. live your truth. πŸ’…)

The string itself? it may start with an arbitrary amount of white space β€” whatever isspace(3) says counts as white space β€” followed by a single optional + or - sign. πŸ¦‹

Then, if base is zero or 16, the string may include a 0x or 0X prefix, and the number gets read in base 16. otherwise? a zero base is taken as 10 (decimal), unless the next character is 0, in which case it's taken as 8 (octal). sneaky. 😌

The rest of the string gets converted to an uintmax_t value in the obvious manner, stopping either at the end of the string or at the first character that isn't a valid digit in the given base. and yes, for bases above 10, the letter A β€” upper or lower case, she does not discriminate β€” represents 10, B represents 11, and so on and so forth, all the way up to Z representing 35. alphabet girls rise. πŸ”€βœ¨

Now, if endptr is non-nil, strtou() stores the address of the first invalid character in *endptr. BUT β€” and this is important, don't skip it β€” if there were no digits at all, strtou() stores the original value of nptr in *endptr. so like… if *nptr is not '\0' but **endptr is '\0' on return, congrats babe, the entire string was valid. πŸŽ‰


πŸ’« RETURN VALUES πŸ’«

  • strtou() always returns the closest value in the range specified by the lo and hi arguments. it's a clamps girly. 🫢
  • The errno value is guaranteed to be left unchanged. untouched. unbothered. exactly as she was. πŸ’…
  • Errors get stored as the conversion status in the rstatus argument.

🌈 EXAMPLES 🌈

The following example will always return a number in the [1..99] range no matter what the input is, and warn if the conversion failed. no matter WHAT the input. chaotic string? doesn't matter. it's contained. πŸ”₯

int e;
uintmax_t lval = strtou(buf, NULL, 0, 1, 99, &e);
if (e)
        warnc(e, "conversion of `%s' to a number failed, using %ju",
            buf, lval);

πŸ’€ ERRORS πŸ’€

  • [ECANCELED] β€” The string did not contain any characters that were converted. (nothing happened. zero. zilch. the conversion said "not today". 😭)
  • [EINVAL] β€” The base is not between 2 and 36 and does not contain the special value 0. (bestie that base is illegal, put it back. πŸ™ˆ)
  • [ENOTSUP] β€” The string contained non-numeric characters that did not get converted. In this case, endptr points to the first unconverted character. (it did some of the work and then stopped. relatable.)
  • [ERANGE] β€” The given string was out of range; the value converted has been clamped; or the range given was invalid, i.e. lo > hi. (clamped!! also if you handed it lo > hi that's on you and it is not okay. 😀)
⚠️ okay important lore: the range check is more important than the unconverted characters check, and it is performed first. so if a program needs to know whether there were unconverted characters when an out-of-range number has been provided, it needs to supply and test endptr itself. the function is not gonna do that emotional labor for you. 🫠

πŸ‘€ SEE ALSO πŸ‘€

atof(3), atoi(3), atol(3), atoll(3), strtod(3), strtoi(3bsd), strtoimax(3), strtol(3), strtoll(3), strtoul(3), strtoull(3), strtoumax(3)


πŸ“œ STANDARDS πŸ“œ

The strtou() function is a NetBSD extension. it's giving niche, it's giving special edition. πŸ¦‹

πŸ•°οΈ HISTORY πŸ•°οΈ

The strtou() function first appeared in NetBSD 7.0. OpenBSD introduced the strtonum(3bsd) function for the same purpose, but the interface makes it impossible to properly differentiate illegal returns. (we respect the attempt but the interface said "no differentiation for you". πŸ˜”)

πŸ› BUGS πŸ›

Ignores the current locale. that's it. that's the whole bug. she's got one flaw and she owns it. πŸ’…


and that's the whole page, bestie!! πŸŽ€ this one came from the Debian packaging, dated January 20, 2024 β€” so go forth, convert your strings, clamp your ranges, and never touch errno again. slay. πŸ’–βœ¨πŸŒΈπŸ¦‹πŸ‘‘

πŸ“¦ where this page comes from