std::isxdigit(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’… NAME πŸ’…

std::isxdigit β€” literally std::isxdigit, that's the whole name bestie, we're not doing anything fancy here πŸŽ€

This page lives in the C++ Standard Libary manual, section 3 β€” and yes that's their typo, not mine, I would never 😭 but I'm keeping it because facts are facts.

✨ SYNOPSIS ✨

Okay so first of all it's defined in header <cctype>, and the signature is exactly this:

int isxdigit( int ch );

What it does: checks if the given character is a hexadecimal numeric character β€” and the hex crew is exactly:

0123456789abcdefABCDEF

That's it. That's the whole squad πŸ’…

⚠️ Big caveat, pay attention bestie: the behavior is undefined if the value of ch is not representable as unsigned char and is not equal to EOF. Undefined = ✨anything can happen✨ = not the vibe we want.

🌸 PARAMETERS 🌸

  • ch β€” the character to classify 🫢 (what's its deal, what's its classification, we're about to find out)

πŸ‘‘ RETURN VALUE πŸ‘‘

Non-zero value if the character is a hexadecimal numeric character, zero otherwise. That's it. Binarily yes or no, icon behavior.

πŸ’€ NOTES πŸ’€

Okay this part is lowkey the important part so listen up πŸ™ˆ

std::isdigit and std::isxdigit are the only standard narrow character classification functions that are not affected by the currently installed C locale β€” although some implementations (e.g. Microsoft in 1252 codepage) may classify additional single-byte characters as digits. So like… mostly locale-proof, but not 100% universally, iykyk.

And like all other functions from <cctype>, the behavior of std::isxdigit is undefined if the argument's value is neither representable as unsigned char nor equal to EOF 😭😭

To use these functions safely with plain chars (or signed chars), convert the argument to unsigned char first, like this:

bool my_isxdigit(char ch)
{
    return std::isxdigit(static_cast<unsigned char>(ch));
}

Similarly, they should not be directly used with standard algorithms when the iterator's value type is char or signed char. Instead, convert the value to unsigned char first:

int count_xdigits(const std::string& s)
{
    return std::count_if(s.begin(), s.end(),
                      // static_cast<int(*)(int)>(std::isxdigit)     // wrong
                      // [](int c){ return std::isxdigit(c); }       // wrong
                      // [](char c){ return std::isxdigit(c); }      // wrong
                         [](unsigned char c){ return std::isxdigit(c); } // correct
                        );
}

Note the three commented-out attempts marked // wrong β€” those are the traps, do not step in them 🚩 The [](unsigned char c) one is marked // correct, be like that one ⭐

πŸ¦‹ EXAMPLE πŸ¦‹

Run this code, it's cute:

#include <cctype>
#include <climits>
#include <iostream>

int main()
{
    for (int c = 0; UCHAR_MAX >= c; ++c)
        if (isxdigit(c))
            std::cout << static_cast<char>(c);
    std::cout << '\n';
}

πŸ“ OUTPUT πŸ“

0123456789ABCDEFabcdef

It printed the entire hex alphabet twice (lower + upper) and honestly? Slayed πŸ”₯

🌈 SEE ALSO 🌈

  • isxdigit(std::locale) β€” checks if a character is classified as a hexadecimal digit by a locale β€” (function template)
  • iswxdigit β€” checks if a wide character is a hexadecimal character β€” (function)
  • C documentation for isxdigit

And then there's the giant ASCII table of destiny πŸ‘‡ every ASCII value, its characters, and which of the classification functions say yes to it β€” narrow ones (iscntrl isprint isspace isblank isgraph ispunct isalnum isalpha isupper islower isdigit isxdigit) plus the wide ones (iswcntrl iswprint iswspace iswblank iswgraph iswpunct iswalnum iswalpha iswupper iswlower iswdigit iswxdigit). Dropping it raw so nothing gets lost πŸ’–

       ASCII values            characters    iscntrl  isprint  isspace  isblank  isgraph  ispunct  isalnum  isalpha  isupper  islower  isdigit  isxdigit decimal hexadecimal   octal                   iswcntrl iswprint  iswspace iswblank iswgraph iswpunct iswalnum iswalpha iswupper iswlower  iswdigit iswxdigit
       0–8     \x0–\x8     \0–\10    control codes   β‰ 0       0        0        0        0        0        0        0        0        0        0
                                     (NUL, etc.)
       9       \x9         \11       tab (\t)        β‰ 0       0        β‰ 0       β‰ 0       0        0        0        0        0        0        0        0
                                     whitespaces
       10–13   \xA–\xD     \12–\15   (\n, \v, \f,    β‰ 0       0        β‰ 0       0        0        0        0        0        0        0        0        0
                                     \r)
       14–31   \xE–\x1F    \16–\37   control codes   β‰ 0       0        0        0        0        0        0        0        0        0        0        0
       32      \x20        \40       space           0        β‰ 0       β‰ 0       β‰ 0       0        0        0        0        0        0        0        0
       33–47   \x21–\x2F   \41–\57   !"#$%&'()*+,-./ 0        β‰ 0       0        0        β‰ 0       β‰ 0       0        0        0        0        0        0
       48–57   \x30–\x39   \60–\71   0123456789      0        β‰ 0       0        0        β‰ 0       0        β‰ 0       0        0        0        β‰ 0       β‰ 0
       58–64   \x3A–\x40   \72–\100  :;<=>?@         0        β‰ 0       0        0        β‰ 0       β‰ 0       0        0        0        0        0        0
       65–70   \x41–\x46   \101–\106 ABCDEF          0        β‰ 0       0        0        β‰ 0       0        β‰ 0       β‰ 0       β‰ 0       0        0        β‰ 0
       71–90   \x47–\x5A   \107–\132 GHIJKLMNOP      0        β‰ 0       0        0        β‰ 0       0        β‰ 0       β‰ 0       β‰ 0       0        0        0
                                     QRSTUVWXYZ
       91–96   \x5B–\x60   \133–\140 [\]^_`          0        β‰ 0       0        0        β‰ 0       β‰ 0       0        0        0        0        0        0
       97–102  \x61–\x66   \141–\146 abcdef          0        β‰ 0       0        0        β‰ 0       0        β‰ 0       β‰ 0       0        β‰ 0       0        β‰ 0
       103–122 \x67–\x7A   \147–\172 ghijklmnop      0        β‰ 0       0        0        β‰ 0       0        β‰ 0       β‰ 0       0        β‰ 0       0        0
                                     qrstuvwxyz
       123–126 \x7B–\x7E   \172–\176 {|}~            0        β‰ 0       0        0        β‰ 0       β‰ 0       0        0        0        0        0        0
       127     \x7F        \177      backspace       β‰ 0       0        0        0        0        0        0        0        0        0        0        0
                                     character (DEL)

And that's the whole page! Source and version teaser: this came from http://cppreference.com, dated 2024.06.10, filed under std::isxdigit(3) β€” go convert your chars to unsigned char and stay safe out there bestie πŸ«ΆπŸ’œβœ¨

πŸ“¦ where this page comes from