Thread: Program to change lowercase to uppercase and vice-versa

  1. #1
    Registered User
    Join Date
    Oct 2011
    Posts
    81

    Program to change lowercase to uppercase and vice-versa

    This program is supposed to take a user input string and change lower case characters to upper case and vice versa. It works except that for spaces between words it puts @ and then it adds some weird characters at the end of every string. What is wrong?

    Code:
    #include<stdio.h>
    #include<string.h>
    int main(){
      char str[20];
      int i;
      printf("Enter any string:");
      gets(str);
      for(i=0;i<=strlen(str);i++){
                if(str[i]>=97&&str[i]<=122)
                str[i]=str[i]-32;
        else
        str[i]=str[i]+32;
    }
        printf("Proper capitalisation is of great importance\n");    
        printf("%s\n",str);
      return 0;
    }

  2. #2
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    You're unconditionally adding 32 to any character which isn't between 'a' and 'z', including spaces, numbers, punctuation and so on.

    Also, in order of relative importance :

    Fix the indentation of the code
    Don't use magic numbers - use constants such as 'a', 'A', -'A'+'a' and so on.
    You'd be better off using functions such as isuppper or islower to test for upper or lower case letters
    gets is unsafe - look into using fgets(str, sizeof(str), stdin) instead.

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Code:
    if(str[i]>=97&&str[i]<=122)
        str[i]=str[i]-32;
    else
        str[i]=str[i]+32;
    So if str[i] is between 97 and 122 (lowercase), you subtract 32 to make it upper case. Then you have an else, which accounts for every other character that isn't lowercase, including spaces, punctuation, etc, and you add 32 to that to "make it lowercase".

    Also, stop using magic numbers that are specific to ASCII (which not everybody uses). How about using functions like isupper, islower, toupper and tolower? Just #include <ctype.h>.

  4. #4
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    Jinx

  5. #5
    Registered User
    Join Date
    Oct 2011
    Posts
    81
    Quote Originally Posted by anduril462 View Post
    Code:
    if(str[i]>=97&&str[i]<=122)
        str[i]=str[i]-32;
    else
        str[i]=str[i]+32;
    So if str[i] is between 97 and 122 (lowercase), you subtract 32 to make it upper case. Then you have an else, which accounts for every other character that isn't lowercase, including spaces, punctuation, etc, and you add 32 to that to "make it lowercase".

    Also, stop using magic numbers that are specific to ASCII (which not everybody uses). How about using functions like isupper, islower, toupper and tolower? Just #include <ctype.h>.
    I absolutely agree. If there is something easier then its that that we should use. However, our lecturer has not taught it to us yet which is ridiculous.

  6. #6
    Registered User
    Join Date
    Oct 2011
    Posts
    81
    Perfect thanks!

  7. #7
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    Quote Originally Posted by Interista View Post
    I absolutely agree. If there is something easier then its that that we should use. However, our lecturer has not taught it to us yet which is ridiculous.
    Nope, it's important to understand the concept of how characters map to integers and back again. Later is the time for shortcuts written by other people who already understand those concepts, but now's the time to make sure you become one of them.

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by anduril462 View Post
    Also, stop using magic numbers that are specific to ASCII (which not everybody uses). How about using functions like isupper, islower, toupper and tolower? Just #include <ctype.h>.
    If, for sake of discussion, we do not want to use those standard library functions and we are willing to limit our code for english speakers, we can use a property of all character sets.

    All real-world character sets (ASCII, EDCDIC, etc) place the letters 'A' through 'Z' in sequence (so 'B' is equivalent to 'A' + 1, 'Z' is equivalent to 'A' + 25, etc) and the letters 'a' through 'z' also in sequence for all real-world character sets. Also, in all real-world character sets, the letters have positive values (i.e. neither 'A' nor 'a' are negative). The problem, however, is that the relationship between 'A' and 'a' (for example, number of characters intervening between them) does vary between character sets.

    So, to avoid the magic numbers, it is possible to do this (for a conversion from upper to lower case).
    Code:
    if (x >= 'A' && x <= 'Z)
    {
         x -= 'A';    //   yields a value in the range 0 to 25
         x += 'a';
    }
    This will work for any real-world character set. I've broken the code in the body of the if block into two lines to describe what is actually happening.

    The limitation of this approach is that it is not necessarily applicable for natural languages other than english. The standard functions (isupper(), tolower(), etc) are "locality aware".

    Quote Originally Posted by Interista View Post
    I absolutely agree. If there is something easier then its that that we should use. However, our lecturer has not taught it to us yet which is ridiculous.
    As I discussed in your previous thread, you are speaking rubbish.

    To make a point, this thread gives you a solution to one of your homework exercises. However, you might want to keep in mind that your lecturer probably expects you to learn by doing, whereas you expect to be spoon-fed.
    Last edited by grumpy; 11-03-2011 at 03:35 PM.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  9. #9
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    Quote Originally Posted by grumpy View Post
    All real-world character sets (ASCII, EDCDIC, etc) place the letters 'A' through 'Z' in sequence
    It's the numbers that are guaranteed to be sequential, letters aren't. Certainly not in EBCDIC where, for example, I = 0xC9 and J = 0xD1

    Also, in all real-world character sets, the letters have positive values (i.e. neither 'A' nor 'a' are negative)
    Again, this isn't true for EBCDIC assuming a signed char type.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 12
    Last Post: 07-05-2010, 07:57 PM
  2. Converting 32 bit binary IP to decimal IP (vice-versa)
    By Mankthetank19 in forum C Programming
    Replies: 15
    Last Post: 12-28-2009, 07:17 PM
  3. int to char and vice versa
    By mekaj in forum C++ Programming
    Replies: 13
    Last Post: 12-12-2005, 11:35 AM
  4. Problem: far to near copy, and vice versa
    By aaronc in forum C Programming
    Replies: 1
    Last Post: 06-16-2004, 06:37 AM
  5. Binary to ascii and vice versa
    By thenrkst in forum C++ Programming
    Replies: 13
    Last Post: 03-30-2003, 01:17 AM