6

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
Robert Andrzejuk
  • 5,076
  • 2
  • 22
  • 31
Andrew Mbugua
  • 437
  • 1
  • 6
  • 16
  • 2
    Where is a question? – rafix07 Feb 12 '20 at 10:25
  • 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. – Andrew Mbugua Feb 12 '20 at 10:27
  • Sorry for forgetting that area – Andrew Mbugua Feb 12 '20 at 10:27
  • 1
    @Code_Infinity please don't write comments for clarification but [edit] your question and put all clarifications _there_. – Jabberwocky Feb 12 '20 at 10:56
  • @Code_Infinity should cast the `std::tolower(letter)` or `std::toupper(letter)` output to `char` – Mandy007 Feb 12 '20 at 16:43

3 Answers3

9

std::tolower and std::toupper return int, not char (due to it's legacy origin from Cthere 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.

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
  • 3
    `toupper()` and `tolower()` returning `int` is not just a "legacy from C". 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 specialisations 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. – Peter Feb 12 '20 at 11:02
2

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
NutCracker
  • 11,485
  • 4
  • 44
  • 68
0
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;

}
Mohammed Deifallah
  • 1,290
  • 1
  • 10
  • 25
  • 6
    @Code_Infinity Note: the C style cast used in this answer is often considered bad style in C++. Better not get into the habit of using it. – hyde Feb 12 '20 at 10:45
  • 2
    @hyde what is the difference between c style cast and c++ style cast. Actually they are doing same thing an output manner.It is a coding issue which is "just dont use C in C++ vice versa". Could you clarify it a little bit, thanks. – Nazim Feb 12 '20 at 11:31
  • 5
    @Nazim C-style casts are dangerous. You are basically telling compiler "I don't care about type safety, do *everything* to make this type another type". C++ style casts have greater degree of control, e.g. `static_cast` wouldn't cast away constness by accident. This is well explained in [this question](https://softwareengineering.stackexchange.com/questions/50442/c-style-casts-or-c-style-casts) on [softwareengineering.se] – Yksisarvinen Feb 12 '20 at 11:35
  • Even better explanation when to use which cast: [When should static_cast, dynamic_cast, const_cast, reinterpret_cast, "C-style and Function-style" be used?](https://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used/332086#332086) – Robert Andrzejuk Feb 14 '20 at 02:35