1.11M Members

Change lower case to UPPER CASE

 
0
 

I'm asked to write a program in which the user inputs a letter and the program converts it to lower case if it's UPPER and vis versa.

I have written this program and it worked:

#include<iostream>
using namespace std;
int main()
{
char letter;
cout<<"Enter any letter"<<endl;
cin>>letter;
if(letter>=97&&letter<=122)
{
letter=letter-32;
cout<<"The UPPER CASE letter is: "<<letter<<endl;
}
else
{
letter=letter+32;
cout<<"The lower case letter is: "<<letter<<endl;
}
system("pause");

return 0;
}

my proplem is that someone told me about another way to write this program but I can't understand what did he use!

which is:

#include<iostream>
using namespace std;
int main()
{
char x;
cout<<"Enter any letter"<<endl;
cin>>x;
cout<<(x=(x>='A'&&x<='Z')?x+=' ':x-=' ')<<endl;

return 0;
}

I want to know how it works?!
Thanks alot.

 
2
 

The most portable way to do it is to use the macro toupper() and tolower(). Your program only works if the language is English and uses standard ascii character set. See this page

#include <ctype.h>

int main()
{
   char c = 'A';
   if( isupper(c) )
       c = tolower(c);
   else
       c = toupper(c);
}
 
0
 

@AD: toupper() and tolower() seem to return int and not char.
Also if I recall correctly C++ has new style headers: #include <cctype>.

 
1
 

@AD: toupper() and tolower() seem to return int and not char.

That's only to support an argument of EOF (in which case EOF is the return value). If you never expect to pass EOF, such as when it's a stopping condition prior to calling toupper() or tolower(), there's no need to use int. However, your compiler might warn about a narrowing conversion, in which case a cast is justified:

// Option 1: Use int
int foo = tolower(c);

// Option 2: Cast to char
char bar = (char)tolower(c);

Usually the destination is a string, or something along those lines, so the cast is usually the desirable approach for silencing a warning you know is spurious in that specific situation.

And of course, I shouldn't leave without mentioning that the parameter type is int, but the value range is that of unsigned char or EOF. So you generally want to enforce unsigned char on the argument to account for when vanilla char on the implementation is signed:

char foo = (char)tolower((unsigned char)c);

Otherwise you might encounter a weird situation where tolower() and friends do a table lookup using a negative value and all hell breaks loose for no apparent reason. Those are tricky bugs to troubleshoot.

 
1
 

I want to know how it works?!

This code:
someCondition ? someThingToReturn: someThingElseToReturn
works as follows -

someCondition is evaluated.
If it's true, then someThingToReturn is returned.
If it's false, someThingElseToReturn is returned.

So now that you know that, let's look at the condition.
x>='A'&&x<='Z'
So, this will be true if x is between 'A' amnd 'Z' (i.e. it's true if x is upper case to begin with, and false if x is lower case).

So, if x is upper case, this is what gets returned:
x+=' '
Aha. This takes x, adds ' ' to it, and returns it. You can see from the ASCII chart that the char ' ' has a value 32. You can also see from that table that if you add 32 to an upper case letter, it becomes the lower case. So if x is upper case, it gets made lower case.

If x begins as lower case, then you can see that this x-=' ' subtracts 32, so if x begins as lower case, it is made upper case.

So, this code (x>='A'&&x<='Z')?x+=' ':x-=' ') changes the case of x, and then returns x, which is then assigned to itself ( the x= bit at the front). That x= bit is actually unnecessary, as this code (x>='A'&&x<='Z')?x+=' ':x-=' ') changes the case of x. The code would be better written:

#include<iostream>
using namespace std;
int main()
{
char x;
cout<<"Enter any letter"<<endl;
cin>>x;
cout<<((x>='A'&&x<='Z')?x+=' ':x-=' ')<<endl;  // NO x=
return 0;
}
 
1
 

This code: cout<<(x=(x>='A'&&x<='Z')?x+=' ':x-=' ') works like this:

if(x = capital_letter)
   cout << x + 32;
else
   cout << x - 32;

Because this kind of "if" construct is used so often, the designers of C developed this statement using the conditional operator ?:

x = (test condition) ?  5 : 10;

If the test condition evaluates as true (non zero) then 5 is selected for x, else 10 is selected for x. In other words, the question is (?) is x going to equal 5 or else 10? If the test condition is true, then x will equal 5, else 10. So:

char = (char > 'Z') ? char -= 32 : char += 32;
cout << char;

The question above is, "Is char greater than capital Z? If so, then char is a lower case and needs to have 32 subtracted from it, else it is an upper case letter and needs 32 (' ') added to it. It all boils down to which one will be selected, the -32 or the +32 for char.

Like I said, this is just a one line replacement for the if - else statement above and does the same thing.

You
This article has been dead for over six months: Start a new discussion instead
Post:
Start New Discussion
Tags Related to this Article