std::isprint(3)

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

πŸ’– NAME πŸ’–

std::isprint β€” and yes bestie, that is literally the whole name, it's std::isprint, no notes, no subtitle, we move.


✨ SYNOPSIS ✨

Okay so this one lives in the header <cctype> and the signature is giving minimalist:

int isprint( int ch );

It checks if ch is a printable character as classified by the C locale you currently have installed. In the default, "C" locale, the printable ones are:

  • digits (0123456789)
  • uppercase letters (ABCDEFGHIJKLMNOPQRSTUVWXYZ)
  • lowercase letters (abcdefghijklmnopqrstuvwxyz)
  • punctuation characters:
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
  • space ( )
🚨 genuine warning, not a vibe: the behavior is undefined if the value of ch is not representable as unsigned char and is not equal to EOF. Like, undefined undefined. Respect it.

🌸 PARAMETERS 🌸

  • ch β€” the character you want classified. That's it. That's the whole job.

πŸ”₯ RETURN VALUE πŸ”₯

Non-zero value if the character can be printed, zero otherwise. Simple queen behavior.


πŸ¦‹ NOTES πŸ¦‹

Like all the other functions from <cctype>, the behavior of std::isprint is undefined if the argument's value is neither representable as unsigned char nor equal to EOF. So to use these functions safely with plain chars (or signed chars), convert the argument to unsigned char first:

bool my_isprint(char ch)
{
    return std::isprint(static_cast<unsigned char>(ch));
}

Same energy for standard algorithms: lowkey do not use them directly when the iterator's value type is char or signed char. Convert the value to unsigned char first, bestie:

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

Notice how the comments literally spell out which lambdas are // wrong and which one is // correct β€” the docs ate that, no cap.


πŸŽ€ EXAMPLE πŸŽ€

The docs be like // Run this code and honestly? Run it. It's iconic:

#include <cctype>
#include <clocale>
#include <iostream>

int main()
{
    unsigned char c = '\xa0'; // the non-breaking space in ISO-8859-1

    std::cout << "isprint(\'\\xa0\', default C locale) returned "
              << std::boolalpha << (bool)std::isprint(c) << '\n';

    std::setlocale(LC_ALL, "en_GB.iso88591");
    std::cout << "isprint(\'\\xa0\', ISO-8859-1 locale) returned "
              << std::boolalpha << (bool)std::isprint(c) << '\n';
}

⭐ possible output ⭐

isprint('\xa0', default C locale) returned false
isprint('\xa0', ISO-8859-1 locale) returned true

See how the locale swap completely changes the answer? Main character energy from a single std::setlocale call. 🫢


πŸ‘‘ SEE ALSO πŸ‘‘

  • isprint(std::locale) β€” checks if a character is classified as printable by a locale (function template)
  • iswprint β€” checks if a wide character is a printing character (function)
  • C documentation for isprint

πŸ“Š the ASCII values table (yes, the whole thing) πŸ“Š

The table columns are, in order: ASCII values / characters / then iscntrl, isprint, isspace, isblank, isgraph, ispunct, isalnum, isalpha, isupper, islower, isdigit, isxdigit / decimal, hexadecimal, octal / and the wide twins iswcntrl, iswprint, iswspace, iswblank, iswgraph, iswpunct, iswalnum, iswalpha, iswupper, iswlower, iswdigit, iswxdigit. Here's every row, fully intact, zero skipped 🧚:

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

and that's the whole page, bestie β€” every flag, every value, every // wrong comment preserved with love πŸ’…

shoutout to cppreference.com, dated 2024.06.10, for originally serving up std::isprint(3) β€” this glow-up is for you πŸŽ€βœ¨

πŸ“¦ where this page comes from