>but when i run it it does not do the conversion
You don't print the value of ch after the conversion.
>#include<iostream.h>
This is an old header that is no longer a part of the C++ language. Use <iostream> instead. You also need to consider namespaces, but for now simply adding using namespace std; will suffice.
>#include<conio.h>
This is a nonstandard header that is not supported by all compilers. Even those compilers that do support it offer different contents. That's definitely not conducive to robust and portable programs. Remove this and replace getch with cin.get.
>void main()
main does not, and never has, had a return type of void. The return type of main is int, and anything else is wrong.
>clrscr();
This is one of the functions that is pretty much only supported by Borland. Clearing the screeen when running a console program is almost always antisocial and it serves no useful purpose, so you shouldn't do it.
>{
There's no need to introduce a block before your first if statement. You can safely remove it because it's just clutter.
>if((ch>=65)&&(ch<=122))
Don't use the ASCII values for a test like this, they're not portable at all. A slightly better way would be:
if ( ch >= 'A' && ch <= 'z' )
But there are two distinct issues with this. The first is that between the upper case letters and the lower case letters in the ASCII table, there are special characters starting at 91 and ending at 96 that are
not letters. You handle this later, sort of, but a single test is more clear:
if ( ( ch >= 'A' && ch <= 'Z' ) || ( ch >= 'a' && ch <= 'z' ) )
The second issue is that while you are no longer using ASCII codes in favor of something more portable, you would still be relying on the fact that the letters have contiguous values. This is not true of all character sets, and ASCII is not the only character set out there. While you aren't likely to be using a machine that has something besides ASCII, it's a good idea to get into the habit of programming portably as early as possible.
So what's the easy solution for the second issue? Use the standard library function isalpha in the <cctype> header:
This covers both the first and second issues, but some teachers will freak if you use something that hasn't been taught even if it is far superior to the naive way they were teaching.
>if((ch>=97)&&(ch<=122))
This is where you make the attempt at determining lower case, but the same arguments apply as to the test two lines up. A much better solution would be the standard function islower, also in the <cctype> header.
>ch=ch-32;
Once again, using ASCII code is not portable or obvious. You can do this instead if you don't mind assuming the ASCII character set (because it relies on the letters being contiguous):
It's a more idiomatic way of saying that you want to convert an ASCII lower case letter to upper case. 'A' - 'a' is -32 in ASCII, so by adding that to ch, you subtract 32 and have the upper case equivalent. The inverse can be done with a similar test:
Of course, for both tests and even better solution is toupper and tolower from <cctype>. That way your code is portable.
Here is the code with all of the changes I've suggested:
#include <cctype>
#include <iostream>
using namespace std;
int main()
{
char ch;
cout<<"Enter a character: ";
cin>> ch;
if ( isalpha ( ch ) ) {
if ( isupper ( ch ) ) {
ch = tolower ( ch );
cout<<"The lower case equivalent is "<< ch <<endl;
}
else {
ch = toupper ( ch );
cout<<"The upper case equivalent is "<< ch <<endl;
}
}
else
cout<<"The character is not a letter"<<endl;
cin.get();
}
There is still a problem though. The first call to cin>> probably left a newline in the input stream. Because cin.get stops reading at a newline, it will appear that the call to cin.get is ignored. The solution is to read characters until a newline is reached. You can do it any number of ways, but the simplest is a loop:
while ( cin.get ( ch ) && ch != '\n' )
;
Also, we can tighten up the code by removing the assignment to ch when performing the case conversion. We can do this because the new value of ch isn't used except for printing once:
#include <cctype>
#include <iostream>
using namespace std;
int main()
{
char ch;
cout<<"Enter a character: ";
cin>> ch;
if ( isalpha ( ch ) ) {
if ( isupper ( ch ) )
cout<<"The lower case equivalent is "<< static_cast<char> ( tolower ( ch ) ) <<endl;
else
cout<<"The upper case equivalent is "<< static_cast<char> ( toupper ( ch ) ) <<endl;
}
else
cout<<"The character is not a letter"<<endl;
// Flush the input stream
while ( cin.get ( ch ) && ch != '\n' )
;
cin.get();
}
I'm sure you'll notice that I used static_cast<char> for the toupper and tolower calls. The reason for this is because cout automagically determines the type of the object and prints it accordingly. Because toupper and tolower return int, cout will print the ASCII codes rather than the character representations. So the values must be cast to char before they will be printed correctly. This was done implicitly when we were assigning the result of toupper and tolower to ch, but good compilers would give you a warning about assigning from a wider type (int) to a narrower type (char). For the first code to compile cleanly, a cast would still have been needed.
Here is the same code assuming ASCII, without using the useful library functions that your teacher will probably bitch at you for using.
#include <iostream>
using namespace std;
int main()
{
char ch;
cout<<"Enter a character: ";
cin>> ch;
if ( ( ch >= 'A' && ch <= 'Z' ) || ( ch >= 'a' && ch <= 'z' ) ) {
if ( ch >= 'A' && ch <= 'Z' )
cout<<"The lower case equivalent is "<< static_cast<char> ( ch + 'a' - 'A' ) <<endl;
else
cout<<"The upper case equivalent is "<< static_cast<char> ( ch + 'A' - 'a' ) <<endl;
}
else
cout<<"The character is not a letter"<<endl;
// Flush the input stream
while ( cin.get ( ch ) && ch != '\n' )
;
cin.get();
}
Another way to order the tests to make things slightly clearer would be:
#include <iostream>
using namespace std;
int main()
{
char ch;
cout<<"Enter a character: ";
cin>> ch;
if ( ch >= 'A' && ch <= 'Z' )
cout<<"The lower case equivalent is "<< static_cast<char> ( ch + 'a' - 'A' ) <<endl;
else if ( ch >= 'a' && ch <= 'z' )
cout<<"The upper case equivalent is "<< static_cast<char> ( ch + 'A' - 'a' ) <<endl;
else
cout<<"The character is not a letter"<<endl;
// Flush the input stream
while ( cin.get ( ch ) && ch != '\n' )
;
cin.get();
}
If you aren't allowed to use the functions from <cctype> and you still need something portable then you could write your own. They wouldn't be nearly as efficient though because library functions themselves use nonportable constructs and hide them in a standardized interface that works everywhere. The easiest way to write portable isupper, islower, toupper, and tolower functions would be by searching for the character in a string:
#include <iostream>
using namespace std;
bool is_upper ( char ch )
{
static char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for ( int i = 0; upper[i] != '\0'; i++ ) {
if ( ch == upper[i] )
return true;
}
return false;
}
bool is_lower ( char ch )
{
static char lower[] = "abcdefghijklmnopqrstuvwxyz";
for ( int i = 0; lower[i] != '\0'; i++ ) {
if ( ch == lower[i] )
return true;
}
return false;
}
char to_lower ( char ch )
{
static char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static char lower[] = "abcdefghijklmnopqrstuvwxyz";
for ( int i = 0; upper[i] != '\0'; i++ ) {
if ( ch == upper[i] )
return lower[i];
}
return ch;
}
char to_upper ( char ch )
{
static char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static char lower[] = "abcdefghijklmnopqrstuvwxyz";
for ( int i = 0; lower[i] != '\0'; i++ ) {
if ( ch == lower[i] )
return upper[i];
}
return ch;
}
int main()
{
char ch;
cout<<"Enter a character: ";
cin>> ch;
if ( is_upper ( ch ) )
cout<<"The lower case equivalent is "<< to_lower ( ch ) <<endl;
else if ( is_lower ( ch ) )
cout<<"The upper case equivalent is "<< to_upper ( ch ) <<endl;
else
cout<<"The character is not a letter"<<endl;
// Flush the input stream
while ( cin.get ( ch ) && ch != '\n' )
;
cin.get();
}
Of course, that's probably beyond the scope of your homework, but it's an entertaining exercise that kills a little bit of time.