Thread: Help !

    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    11
    Rep Power
    0

    whitespaces C


    Code:
    #include<stdio.h>
    
    int main() {
    char a[100];
    char *c = a;
    
    printf("Enter Your String: ");
    
    while(1){
    scanf("%s", c);
    for (int k=0; k<100; k++) {
    	//scanf("[^\n]", c);
    	if (*(c+k+1) >= 65 && *(c+k+1) <=90 ) { //capital alphabets to small. 
    		*(c+k+1) = *(c+k+1) +32; 
    	}
    	}
    
    	if (*(c+0) >= 97 && *(c+0) <= 122){
    	*(c+0) = *(c+0) - 32;
    	
    	}
    	printf("%s", c);
    	}
    	return 0;
    	}

    I want to add spaces between my words. If I enter: oUTPUT iNPUT.

    my output is: OutputInput

    How can I add spaces between my words. Please help !
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,417
    Rep Power
    1871
    Please format your code posting, so that it isn't all on one line.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Well, since nobody can read your code, it's anybody's guess. Only we don't like to play guessing games so you're on your own.

    When you posted your message, you could see immediately that your code listing was all frakked up. So why did you leave it that way? Edit your message and correct it! Only then could we even begin to help you.
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    11
    Rep Power
    0
    Originally Posted by dwise1_aol
    Well, since nobody can read your code, it's anybody's guess. Only we don't like to play guessing games so you're on your own.

    When you posted your message, you could see immediately that your code listing was all frakked up. So why did you leave it that way? Edit your message and correct it! Only then could we even begin to help you.
    You don't have to be so rude! All this time I was trying to fix the problem. I am new here so it took me time to figure out the problem. Be nice.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    11
    Rep Power
    0
    Originally Posted by salem
    Please format your code posting, so that it isn't all on one line.
    I fixed it.
  10. #6
  11. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,417
    Rep Power
    1871
    I was thinking more along the lines of this.
    Code:
    #include<stdio.h>
    int main()
    {
      char a[100];
      char *c = a;
      printf("Enter Your String: ");
    //int i;
      while (1) {
        scanf("%s", c);
        for (int k = 0; k < 100; k++) {
          //scanf("[^\n]", c);
          if (*(c + 0) >= 97 && *(c + 0) <= 122) {
            *(c + 0) = *(c + 0) - 32;
          }
        }
        if (*(c + 0) >= 97 && *(c + 0) <= 122) {
          *(c + 0) = *(c + 0) - 32;
        }
        printf("%s", c);
      }
      return 0;
    }
    Indentation is so very important when reading code.

    To print a space between words, consider using "%s " as your format (note the space).

    Also, why all the (c+0) ?
    You're just repeating yourself with the first character.

    > if (*(c + 0) >= 97 && *(c + 0) <= 122)
    Try this for readability.
    if (c[0] >= 'a' && c[0] <= 'z')
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    11
    Rep Power
    0
    Originally Posted by salem
    I was thinking more along the lines of this.
    Code:
    #include<stdio.h>
    int main()
    {
      char a[100];
      char *c = a;
      printf("Enter Your String: ");
    //int i;
      while (1) {
        scanf("%s", c);
        for (int k = 0; k < 100; k++) {
          //scanf("[^\n]", c);
          if (*(c + 0) >= 97 && *(c + 0) <= 122) {
            *(c + 0) = *(c + 0) - 32;
          }
        }
        if (*(c + 0) >= 97 && *(c + 0) <= 122) {
          *(c + 0) = *(c + 0) - 32;
        }
        printf("%s", c);
      }
      return 0;
    }
    Indentation is so very important when reading code.

    To print a space between words, consider using "%s " as your format (note the space).

    Also, why all the (c+0) ?
    You're just repeating yourself with the first character.

    > if (*(c + 0) >= 97 && *(c + 0) <= 122)
    Try this for readability.
    if (c[0] >= 'a' && c[0] <= 'z')
    I did (*(c+0) >=97 && *(c+0) <=122) so that I can make the first alphabet of every sentence capital.
  14. #8
  15. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Absolutely consistent indentation is an absolute requirement when using the K&R style of hiding your open braces at the ends of lines. Also hiding them in the middle of lines, as you did in two cases, only makes matters far worse. Instead, why not use the Allman style; eg (OBTW, I also removed that block of code that had been commented out in order to reduce clutter):
    Code:
    #include<stdio.h>
    
    int main() 
    {
        char a[100];
        char *c = a;
        int k;
        printf("Enter Your String: ");
        scanf("%[^\n]", c);
    
        for (k=0; k<100; k++) 
        {
            //capital alphabets to small. 
            if (*(c+k+1) >= 65 && *(c+k+1) <=90) 
            {
                *(c+k+1) = *(c+k+1) +32;
            }
    	
            //small alphabets to big - only the first alphabet of the sentence. 
            if (*(c+0) >= 97 && *(c+0) <= 122) 
            {
                *(c+0) = *(c+0) - 32;
            }
        }
        printf("%s\n",c);
        return 0;
    }
    While the actual style you choose is a personal matter, you should still be able to see how much more readable this style is. Making your code readable, especially for yourself, is of utmost importance.

    When I compiled and tried to run your program, I got this:
    C:>gcc -Wall caps.c
    caps.c: In function `main':
    caps.c:9: warning: too many arguments for format

    C:>a
    Enter Your String: oUTPUT iNPUT
    ╬├┬w■"

    C:>
    Not at all the output you reported to us. Plus, why did you ignore the warning? Never ignore warnings! And never try to run a program until it has compiled cleaning (ie, no errors nor warnings). Warnings are much more important than error messages!

    The warning is because of the error in your scanf:
    scanf("[^\n]", c);
    You gave it an argument, c, but never told it to expect an argument. You had left out the percent sign. That should have read:
    scanf("%[^\n]", c);
    Please note the percent sign.

    After making that correction, it compiled cleanly and ran:
    C:>gcc -Wall caps.c

    C:>a
    Enter Your String: oUTPUT iNPUT
    Output input

    C:>
    The space in the input is also in the output. Running your code with that one correction, I was unable to duplicate the problem that you reported.
  16. #9
  17. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Originally Posted by Shiningstar
    I did (*(c+0) >=97 && *(c+0) <=122) so that I can make the first alphabet of every sentence capital.
    That isn't what he was telling you.

    'A' == 65
    'Z' == 90
    'a' == 97
    'z' == 122

    Those are very simple facts of life in the Wonderful World of ASCII. Use them! Of course, if you were doing this on a machine that used a different character code, eg EBCDIC (which I learned to use in school on an IBM S/370, not encountering ASCII until working in the real world), then those values would change, but then so would your code with the explicit numeric values need to change.

    The programming convention would be to have written that part of your code thus:
    Code:
            if (*(c+k+1) >= 'A' && *(c+k+1) <='Z') 
            {
                *(c+k+1) = *(c+k+1) +32;
            }
    	
            //small alphabets to big - only the first alphabet of the sentence. 
            if (*(c+0) >= 'a' && *(c+0) <= 'z')
    As you can see, it makes your code much more readable in that anyone can immediately see what you are doing.
  18. #10
  19. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    11
    Rep Power
    0
    Originally Posted by dwise1_aol
    Absolutely consistent indentation is an absolute requirement when using the K&R style of hiding your open braces at the ends of lines. Also hiding them in the middle of lines, as you did in two cases, only makes matters far worse. Instead, why not use the Allman style; eg (OBTW, I also removed that block of code that had been commented out in order to reduce clutter):
    Code:
    #include<stdio.h>
    
    int main() 
    {
        char a[100];
        char *c = a;
        int k;
        printf("Enter Your String: ");
        scanf("%[^\n]", c);
    
        for (k=0; k<100; k++) 
        {
            //capital alphabets to small. 
            if (*(c+k+1) >= 65 && *(c+k+1) <=90) 
            {
                *(c+k+1) = *(c+k+1) +32;
            }
    	
            //small alphabets to big - only the first alphabet of the sentence. 
            if (*(c+0) >= 97 && *(c+0) <= 122) 
            {
                *(c+0) = *(c+0) - 32;
            }
        }
        printf("%s\n",c);
        return 0;
    }
    While the actual style you choose is a personal matter, you should still be able to see how much more readable this style is. Making your code readable, especially for yourself, is of utmost importance.

    When I compiled and tried to run your program, I got this:

    Not at all the output you reported to us. Plus, why did you ignore the warning? Never ignore warnings! And never try to run a program until it has compiled cleaning (ie, no errors nor warnings). Warnings are much more important than error messages!

    The warning is because of the error in your scanf:
    scanf("[^\n]", c);
    You gave it an argument, c, but never told it to expect an argument. You had left out the percent sign. That should have read:
    scanf("%[^\n]", c);
    Please note the percent sign.

    After making that correction, it compiled cleanly and ran:

    The space in the input is also in the output. Running your code with that one correction, I was unable to duplicate the problem that you reported.
    Thank you so much !

    Also I was wondering how can I make every character after a punctuation mark Capital ?

    for example if my input is: input OUTPUT. input output.

    my output should be: Input output. Input output.
  20. #11
  21. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    From my professional experience, I would immediately think of using a state machine, especially if the parsing rules start to get complex. Otherwise, as you are scanning through the string one character at a time, when you encounter a punctuation mark that would require the next character to be upper-case, set a flag and then test that flag every time you process a character, resetting the flag after converting a character to upper-case, of course. The idea of setting and clearing and testing flags is as common as the idea of assigning a value to a variable, so if it's new to you and you don't understand it, let us know.

    I would think that you would want to split off your conversion code into two functions, eg MyToUpper and MyToLower, and then choose which one to call based on which case you want a character to be. Otherwise, you would have either more complex code or duplication of the conversion code.
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    11
    Rep Power
    0
    Originally Posted by dwise1_aol
    From my professional experience, I would immediately think of using a state machine, especially if the parsing rules start to get complex. Otherwise, as you are scanning through the string one character at a time, when you encounter a punctuation mark that would require the next character to be upper-case, set a flag and then test that flag every time you process a character, resetting the flag after converting a character to upper-case, of course. The idea of setting and clearing and testing flags is as common as the idea of assigning a value to a variable, so if it's new to you and you don't understand it, let us know.

    I would think that you would want to split off your conversion code into two functions, eg MyToUpper and MyToLower, and then choose which one to call based on which case you want a character to be. Otherwise, you would have either more complex code or duplication of the conversion code.

    I can use MyToUpper and MyToLower. I did something like this but its not working.

    Code:
    #include<stdio.h>
    
    int main() 
    {
        char a[100];
        char *c = a;
        int k;
        printf("Enter Your String: ");
        scanf("%[^\n]", c);
    
        for (k=0; k<100; k++) 
        {
            //capital alphabets to small. 
    
            if (*(c+k+1) >= 65 && *(c+k+1) <=90) 
            {
                *(c+k+1) = *(c+k+1) +32;
            }
    	// if there is a "." or "!" or "?"
    
    	if (*(c+k+1) == 46 || *(c+k+1) == 33 || *(c+k+1) == 63) 
            {
               (*(c+k+2-1) >= 97 && *(c+k+2-1) <= 122);
    		*(c+k+2-1) = *(c+k+2-1) - 32;
            }
            //small alphabets to big - only the first alphabet of the sentence. 
    
            if (*(c+0) >= 97 && *(c+0) <= 122) 
            {
                *(c+0) = *(c+0) - 32;
            }
    
    	
        }
        printf("%s\n",c);
        return 0;
    }
    My output is not what I expect. I found the ascii values of "." "?' and "!"
  24. #13
  25. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    You're only applying the test to the very next character. Isn't that very next character a blank? That's certainly what it is in the example you gave us.

    And are you always guaranteed that the user will insert one single space after a punctuation mark? What's to keep him for entering two, as I was trained to do in typing class? Or none? That's why I suggested that you set a flag that you then test once you've found the next [A-Za-z] character. IOW, when you detect a condition that you want to remember for use later, you assign 1 (AKA "true") to an int variable that you're using as a flag; that int variable will be set to zero (AKA "false") when that condition does not exist. Then when you finally scan to a letter you test the flag and convert it to upper-case if that flag is true or to lower-case if that flag is false.

    And why aren't you using '.', '!', or '?' instead of the explicit ASCII code values? Is part of the assignment to make the reading of your code extra confusing?

    And why do you keep testing the first character of the string for each and every character you scan in that for-loop? Going into the for-loop, set that flag to true to indicate that the first character is to be capitalized and then be done with it!

IMN logo majestic logo threadwatch logo seochat tools logo