Thread: question about these functions

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    34

    question about these functions

    I'm wondering if anyone could explain how a couple statements in this code works.
    Code:
    int main()
    {
    	char c, c1, c2;
    	printf("enter your sentence\n");
    	while( (c = getchar()) != EOF ){
    		if( c == '%' ){
    			c1 = getchar();
    			c2 = getchar();
    			if( c1 == EOF || c2 == EOF )  exit(0);
    			c1 = tolower(c1);
    			c2 = tolower(c2);
    			if( ! isxdigit(c1) || ! isxdigit(c2) )  exit(0);
    			if( c1 <= '9' )
    				c1 = c1 - '0';
    			else
    				c1 = c1 - 'a' + 10;
    			if( c2 <= '9' )
    				c2 = c2 - '0';
    			else
    				c2 = c2 - 'a' + 10;
    			putchar( 16 * c1 + c2 );
    		} else if( c == '+' )
    			putchar(' ');
    		else
    			putchar(c);
    	}
    	exit(0);
    }
    
    ===============================================
    
    int main()
    {
    	int c;
    	char *h = "0123456789abcdef";
    
    	while( (c = getchar()) != EOF ){
    		if( 'a' <= c && c <= 'z'
    		|| 'A' <= c && c <= 'Z'
    		|| '0' <= c && c <= '9'
    		|| c == '-' || c == '_' || c == '.' )
    			putchar(c);
    		else if( c == ' ' )
    			putchar('+');
    		else {
    			putchar('%');
    			putchar(h[c >> 4]);
    			putchar(h[c & 0x0f]);
    		}
    	}
    	exit(0);
    }
    I know what the code does I've worked several examples, but I'm a bit unsure how it works specifically.
    Code:
    if( ! isxdigit(c1) || ! isxdigit(c2) )  exit(0);
    			if( c1 <= '9' )
    				c1 = c1 - '0';
    			else
    				c1 = c1 - 'a' + 10;
    			if( c2 <= '9' )
    				c2 = c2 - '0';
    			else
    				c2 = c2 - 'a' + 10;
    			putchar( 16 * c1 + c2 );
    why is there a ! in the isxdigit(c1) statement?
    and how does comparing '0' and 'a' and '9' in the if else statements change a Hex value to ASCII?

    My other question is in the second part

    Code:
    putchar(h[c >> 4]);
    putchar(h[c & 0x0f]);
    I don't understand how these two statements function why is there >> and & in them? I've seen them used for nibble operations in microcontrollers but I'm confused what they are doing here. Thank you very much.

  2. #2
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    the '!' is negation. so its saying if either c1 or c2 are not hex numbers then exit. regarding how it changes the hex number to ascii i dont know, i havent really examined and thought about the code. but it just looks like a bunch of arithmetic im sure you could figure out if you checked out the integer values for the characters.

    the second part involves bitwise operators, ive never used them myself but maybe this tutorial will help you: http://www.cprogramming.com/tutorial...operators.html

    hope it helps.

  3. #3
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    The second part is fairly simple. The first one:
    Code:
    putchar(h[c >> 4]);
    The c >> 4 shifts the bits in c to the right, 4 times, essentially leaving you with the upper four bits. (The result is 0 - 15). This is then used as an index to a string to look up the corresponding hexadecimal character.
    The second line, same idea, but with the lower four bits. For example, if c = 0xCD:
    c >> 4 = (0xCD) >> 4 = 0x0C
    The character at position 0x0C in "0123456789abcdef" is 'c'.
    Second line:
    c & 0x0f = (0xCD) & 0x0f = 0x0D
    The character at position 0x0D in "0123456789abdef" is 'd'.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  4. #4
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Code:
    if( 'a' <= c && c <= 'z'
    || 'A' <= c && c <= 'Z'
    || '0' <= c && c <= '9'
    || c == '-' || c == '_' || c == '.' )
    Unfortunately the code is not portable since it assumes ASCII is the only character table out there.

  5. #5
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by cpjust View Post
    Code:
    if( 'a' <= c && c <= 'z'
    || 'A' <= c && c <= 'Z'
    || '0' <= c && c <= '9'
    || c == '-' || c == '_' || c == '.' )
    Unfortunately the code is not portable since it assumes ASCII is the only character table out there.
    It would work for any character set where a..z are consecutive and in order, A..Z are consecutive and in order, and 0..9 are consecutive and in order. Which is essentially 100% of the character sets now in modern use.

  6. #6
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    It would work for any character set where a..z are consecutive and in order, A..Z are consecutive and in order, and 0..9 are consecutive and in order. Which is essentially 100% of the character sets now in modern use.
    Are you sure about that?
    http://www.legacyj.com/cobol/ebcdic.html

  7. #7
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    LOL..... The term "legacy" is ironic.

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    It would work for any character set where a..z are consecutive and in order, A..Z are consecutive and in order, and 0..9 are consecutive and in order. Which is essentially 100&#37; of the character sets now in modern use.
    0..9 are actually guaranteed by the standard to be contiguous, I think. Though letters are not. So you're okay with
    Code:
    char letter = '2';
    int number = letter - '0';
    But anyway, isalpha() and isdigit() and isalnum() etc from <ctype.h> are a much better idea.
    Code:
    if(isalnum(c) || c == '-' || c == '_' || c == '.')
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Beginner's question about functions.
    By Crocodile23 in forum C Programming
    Replies: 4
    Last Post: 01-13-2009, 07:00 AM
  2. Functions Question
    By audinue in forum C Programming
    Replies: 2
    Last Post: 01-09-2009, 09:39 AM
  3. functions question.
    By Boozel in forum C Programming
    Replies: 1
    Last Post: 02-23-2008, 12:38 AM
  4. Question concerning functions
    By Warrax in forum C++ Programming
    Replies: 5
    Last Post: 04-04-2007, 11:00 AM
  5. Question about creating flash functions
    By jbh in forum C++ Programming
    Replies: 8
    Last Post: 11-21-2005, 09:39 AM