简体   繁体   中英

Character converting funtion std::isupper() & std::islower() C++17

I created a simple program to check whether the letter that a user has inputed is either uppercase or lowercase and then convert the lowercase to uppercase and the uppercase to lowercase using the std::isupper() and std::islower() funtion. upon running the code I get the character converion in number form instead of the expected uppercase/lowercase equivalent. Why is that?

#include <iostream>

int main()
{
    char letter {};

    std::cout << "Enter a letter:";

    std::cin >> letter;

    if (std::isupper(letter))
    {
        std::cout << "You entered an uppercase letter"
                     "\n"
                     "the lowercase equivalent is:"
                  << std::tolower(letter);
    }

    if (std::islower(letter))    
    {
        std::cout << "You entered a lowercase letter"
                     "\n"
                     "the uppercase equivalent is:"
                  << std::toupper(letter);
    }

    return 0;
}

Here is an example of an output below:

Enter a letter:F
You entered an uppercase letter.
The lowercase equivalent is:102

Enter a letter:f
You entered a lowercase letter.
The uppercase equivalent is:70

std::tolower and std::toupper return int , not char ( due to it's legacy origin from C there are certain requirements due to which int was chosen, see footnote).

You can cast it back to char to get expected results:

static_cast<char>(std::tolower(letter));

Or you could save the result in a char variable before (if you need that converted latter elsewhere):

letter = std::tolower(letter);
std::cout << letter;

Note: As noticed by Peter in comment, there are requirements for std::tolower and std::toupper that mandate use of type bigger than type actually needed. Quoting it below:

They are also specified as being able to accept and return EOF - a value that cannot be represented as a char but can be represented as an int. C++ iostreams (certainly no legacy from C, being specializations of the templated std::basic_istream ) have a get() function with no arguments that reads a character from the stream, and returns an integral type larger than the character type being read. It is part of the machinery of being able to read a single character from a file and deal with error conditions.

1. option

You can use std::tolower and std::toupper from <locale> header that return the type you would expect them to return.

Take a look at the examples:

char c {'T'};
std::cout << std::tolower(c, std::locale()) << std::endl; // output: t

and

char c {'t'};
std::cout << std::toupper(c, std::locale()) << std::endl; // output: T

Check live example

2. option

You can use std::tolower and std::toupper from <cctype> header that return int that you need to cast to char .

Here are the examples:

char c {'T'};
std::cout << static_cast<char>(std::tolower(c)) << std::endl; // output: t

and

char c {'t'};
std::cout << static_cast<char>(std::toupper(c)) << std::endl; // output: T

Check live example

You can also create your own handy helper functions:

char toupper(char c) {
    return static_cast<char>(std::toupper(static_cast<unsigned char>(c)));
}

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

which you can use like this:

char c1 {'T'};
char c2 {'t'};
std::cout << tolower(c1) << std::endl; // output: t
std::cout << toupper(c2) << std::endl; // output: T
if(std::isupper(letter))
{

  std::cout<<"You entered an uppercase letter"<<"\n"

  "the lowercase equivalent is:" << (char)std::tolower(letter);
}

if (std::islower(letter))

{

  std::cout<<"You entered a lowercase letter"<<"\n"

  "the uppercase equivalent is:" << (char)std::toupper(letter);

}

    return 0;

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM