std::tolower(3)

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

πŸ’– std::tolower(3) πŸ’–

okay so bestie, this one lives in the C++ Standard Library and it's literally the lowercase fairy godmother of <cctype>. let's get into it 🧚✨


✨ NAME ✨

std::tolower β€” yes it's called std::tolower, that's the whole name, no cap πŸ’…


🌸 SYNOPSIS 🌸

It's defined in the header <cctype>, and the signature is:

int tolower( int ch );

So what does it do? It converts the character you hand it into lowercase, following the character conversion rules defined by the currently installed C locale. iykyk β€” the locale matters, we'll get to that πŸ‘€

In the default "C" locale, these uppercase letters:

ABCDEFGHIJKLMNOPQRSTUVWXYZ

get swapped for their respective lowercase letters:

abcdefghijklmnopqrstuvwxyz

slay, iconic, alphabet behavior πŸŽ€


πŸ¦‹ PARAMETERS πŸ¦‹

  • ch β€” the character you want converted. BUT β€” and this is the important part β€” if the value of ch is not representable as unsigned char and doesn't equal EOF, the behavior is undefined. 🫠 like, undefined undefined. don't do that.

πŸ’œ RETURN VALUE πŸ’œ

You get back the lowercase version of ch, or ch unmodified if there's no lowercase version listed in the current C locale. simple as that 🫢


⭐ NOTES ⭐

okay so this is the part everyone skips and then their code explodes 😭

Like all the other functions from <cctype>, the behavior of std::tolower 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:

char my_tolower(char ch)
{
    return static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
}

Similarly β€” and this is the one that gets people β€” they should not be used directly with standard algorithms when the iterator's value type is char or signed char. Instead, convert the value to unsigned char first:

std::string str_tolower(std::string s)
{
    std::transform(s.begin(), s.end(), s.begin(),
                // static_cast<int(*)(int)>(std::tolower)         // wrong
                // [](int c){ return std::tolower(c); }           // wrong
                // [](char c){ return std::tolower(c); }          // wrong
                   [](unsigned char c){ return std::tolower(c); } // correct
                  );
    return s;
}

look at all those commented-out // wrong lines β€” the manpage is literally calling them out for you. the // correct one is the main character here πŸ‘‘πŸ”₯


🌈 EXAMPLE 🌈

// Run this code β€” bestie, go run it:

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

int main()
{
    unsigned char c = '\xb4'; // the character Ε½ in ISO-8859-15
                              // but Β΄ (acute accent) in ISO-8859-1

    std::setlocale(LC_ALL, "en_US.iso88591");
    std::cout << std::hex << std::showbase;
    std::cout << "in iso8859-1, tolower('0xb4') gives "
              << std::tolower(c) << '\n';
    std::setlocale(LC_ALL, "en_US.iso885915");
    std::cout << "in iso8859-15, tolower('0xb4') gives "
              << std::tolower(c) << '\n';
}

see how the same byte \xb4 means two completely different characters depending on the encoding?? that's the vibe check the example is giving you πŸ’€

πŸ“ Possible output πŸ“

in iso8859-1, tolower('0xb4') gives 0xb4
in iso8859-15, tolower('0xb4') gives 0xb8

one stays itself, one transforms β€” that's locale-dependent behavior fr fr πŸ’«


πŸŽ€ SEE ALSO πŸŽ€

  • toupper β€” converts a character to uppercase (function)
  • tolower(std::locale) β€” converts a character to lowercase using the ctype facet of a locale (function template)
  • towlower β€” converts a wide character to lowercase (function)
  • C documentation for tolower

πŸ’… reminder bestie: cast to unsigned char before you call this. not me watching you pass a plain char and hit undefined behavior πŸ™ˆ periodt.

so yeah, that's the whole page πŸ¦‹ β€” courtesy of cppreference.com, version 2024.06.10, and this lil doc is std::tolower(3). go lowercase something cute! πŸ’–βœ¨

πŸ“¦ where this page comes from