Reading a yes/no answer from std::cin Based on this question, I wrote my own implementation of the yesno function I suggested. The function reads an answer until it is either "y" or "yes" or "n" or "no" (case-insensitive).

#include &lt;algorithm&gt;
#include &lt;cctype&gt;
#include &lt;cstdlib&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;

bool yesno(const std::string &amp;prompt)
{
    while (true) {
        std::cout &lt;&lt; prompt &lt;&lt; " [y/n] ";

        std::string line;
        if (!std::getline(std::cin, line)) {
            std::cerr &lt;&lt; "\n";
            std::cerr &lt;&lt; "error: unexpected end of file\n";
            std::exit(EXIT_FAILURE);
        }

        std::transform(line.begin(), line.end(), line.begin(),
                       [](unsigned char x){return std::tolower(x);});

        if (line == "y" || line == "yes") {
            return true;
        }
        if (line == "n" || line == "no") {
            return false;
        }
    }
}

int main()
{
    bool include_digits = yesno("Should the password include digits?");
    if (include_digits) {
        std::cout &lt;&lt; "le1mein\n";
    } else {
        std::cout &lt;&lt; "letmein\n";
    }
}


I took care to:


Include all necessary headers.
Call the std::tolower function with an unsigned char as argument.
Use std::getline instead of the hard-to-control &gt;&gt; operator.
Catch all errors (except for writing to std::cout).


Anything that I missed?
Good job in general, mad props for proper use of cout vs cerr. 

I don't see any "errors" per se, but I do see a few things I personally would have done a bit differently.

Opinion: Not a big fan of std::exit() in anything but main()

A function is supposed to be decontextualized, and having a "will crash the whole program if it fails" as part of the function's contract is just too aggressive in my opinion.

Personally, I'd rather just throw an exception instead. It accomplishes the same thing, and it lets users of the function choose how to handle failures.

Opinion: maybe have a separate prompt for failure?

I would personally explain to the user why he is being asked the same question twice when the input fails to match either criteria.

Opinion: std::transform is overkill here

This is a personal bias, as I find in-place usage of std::transform uncomfortable at best, since a range-based for does as good a job in a much more legible manner. 

Specifically: Having to read the third parameter to understand that it's an inplace transform is just unnecessary cognitive load. I find the following easier to parse:

for(auto&amp; x : line) {
  x = std::tolower(static_cast&lt;unsigned char&gt;(x));
}