Thread: frustration on URL encode-decode

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

    frustration on URL encode-decode

    I'm working on this program to take a person's name, address, and phone number and convert it URL coding print it, then unencode it then print it again normally, with labels over each part. I've run into a couple problems.

    1. I think I'm overcomplicating it first of all.
    2. I want to capture the input but my scanf stops capture when I type a space in my URlEncode function.
    3. I haven't gotten to it yet, but I know I'm going to hit a wall when I try to convert the ASCII characters to hex and printing them to standard output (I've commented that part out)

    Here is my code, I'm not looking for anyone to write my code, but I think I need a better strategy and approach. Thanks.

    Code:
    ////////////////////////////////////////////////////////////////////////////////
    //
    //  File Name  : URL-encoder-decoder.c
    //
    //  Date       : August, 2007
    //
    //  Platform   : IBM PC (Windows XP)
    //
    //  Compiler   : Microsoft Visual C++ 6.0
    //
    ////////////////////////////////////////////////////////////////////////////////
    #define _CRT_SECURE_NO_DEPRECATE
    #define MAX_ARRAY_SIZE 100		// maximum array size
    
    
    //compiler includes
    #include <stdio.h>
    #include <ctype.h>
    #include <stdlib.h>
    #include <string.h>
    
    //constants
    
    //user defined definitions
    typedef struct { // personal_type definition
    	char name[MAX_ARRAY_SIZE];
    	char address[MAX_ARRAY_SIZE];
    	char phoneNumber[MAX_ARRAY_SIZE];
    } PERSONAL_TYPE;
    
    //function prototypes
    PERSONAL_TYPE UrlEncode(void); //function to scan personal info and encode it and print it
    //PERSONAL_TYPE UrlDecode(void); //function to decode URL info 
    void PrintPersonInfo (PERSONAL_TYPE personToPrint); //function to print information after decoded
    
    
    //////////////////////////////////////////////////////////////////////////////// 
    // 
    //  Function Name : main 
    // 
    //  Originated    : August, 2007 
    // 
    //  Abstract      : processing to read values for personal information and 
    //					encode then decode the information
    //
    //  Parameters    : None
    // 
    //  Return Value  : error code - zero
    // 
    //  Misc. I/O     : na
    // 
    //  Revisions     : August, 2007
    // 
    ////////////////////////////////////////////////////////////////////////////////
    int main(void){
    
    //local variables
    PERSONAL_TYPE personOne = {"\0", "\0", "\0"}; // empty data to pass to functions
    
    PrintPersonInfo(personOne); // function call to print personOne information by value
    
    personOne = UrlEncode();
    
    exit(0);
    }
    
    //////////////////////////////////////////////////////////////////////////////// 
    // 
    //  Function Name : PrintPersonInfo
    // 
    //  Originated    : August, 2007 
    // 
    //  Abstract      : function to personal name and address
    // 
    //  Parameters    : PERSONAL_TYPE 
    // 
    //  Return Value  : none
    // 
    //  Misc. I/O     : na
    // 
    //  Revisions     : August, 2007
    // 
    //////////////////////////////////////////////////////////////////////////////// 
     
    void PrintPersonInfo(PERSONAL_TYPE personToPrint) { 
    	printf("\n==================================================================\n");
    	printf("NAME: %s       ADDRESS: %s         PHONE NUMBER: %s\n",personToPrint.address, 
             personToPrint.name, personToPrint.phoneNumber); // prints structures from PERSONAL_TYPE
    } // end function PrintPersonInfo
    
    //////////////////////////////////////////////////////////////////////////////// 
    // 
    //  Function Name : UrlEncode
    // 
    //  Originated    : August, 2007 
    // 
    //  Abstract      : function to scan name, address, phone number and URL encode it
    // 
    //  Parameters    : PERSONAL_TYPE 
    // 
    //  Return Value  : none
    // 
    //  Misc. I/O     : na
    // 
    //  Revisions     : August, 2007
    // 
    ////////////////////////////////////////////////////////////////////////////////
    
    PERSONAL_TYPE UrlEncode(void) { 
    	// local variables
    	inc c;
    
    	PERSONAL_TYPE inputPerson = {"<NULL>", "<NULL>", "<NULL>"}; //empty variable for function
    	
    	//begin
    	printf("Enter your Name: "); // print message to user
    	scanf("%s", inputPerson.name);// scan struture for name and assign to inputPerson
    	printf("Enter your address: ");// print message to user
    	scanf("%s", inputPerson.address);// scan struture for address and assign to inputPerson
    	printf("Enter your phone number: "); // print messsage to user
    	scanf("%s", inputPerson.phoneNumber); // scan struture for phone and assign to inputPerson
    
    	/*
    void UrlEncode(void){ // encoding function
    	int c=0;
    	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]);
    		}
    	 }
    }*/
    return inputPerson; // return struture inputPerson to function caller
     } // end function UrlEncode 
    /////////////////////////////////////////////////////////////////////////
    /*
    void UrlDecode(void){ // decode function
    	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);
    	}
    } */

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    There are a couple of things.

    1. Avoid using scanf() directly. It's easy to use in very simple cases, but it doesn't take too long before your input requirements make scanf() a lot harder to use.

    Code:
    char buff[BUFSIZ];
    if ( fgets( buff, sizeof buff, stdin ) != NULL ) {
    }
    This reads a whole line, including the newline at the end. See the FAQ for ways to remove the newline if that is important. What's more important for you is that the line will contain spaces.

    2. The next step for you is to break the problem down into smaller steps.

    For example, separating input from conversion (or validation)
    Code:
    PERSONAL_TYPE GetPersonInfo ( void ) {
        PERSONAL_TYPE inputPerson;
        char buff[BUFSIZ];
    
        if ( fgets( buff, sizeof buff, stdin ) != NULL ) {
            urlEncode( inputPerson.name, buff );
        }
    
        return inputPerson;
    }
    Since encoding and decoding are no longer reading input, but are supplied everything they need as parameters, testing them is much easier.
    Code:
    int main ( ) {
        char result[100];
        urlEncode( result, "hello world" );
        printf( "Result=%s\n", result );
        return 0;
    }
    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.

  3. #3
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Sorry, I just couldn't help it...
    Code:
    char hexa[]={"0123456789ABCDEFabcdef"};
    char nonencode[]={"abcdefghijklmnopqrstuvwqyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/\\"};
    
    int GetHex(char val){
        int i;
        for(i=0;hexa[i];i++){
            if(hexa[i]==val){
                if(i>15){ return i-6; }
                return i;
            }
        }
        return -1;
    }
    
    void URLDecode(char* dest,int len,char* source){
        int destc=0,i;
        for(i=0;destc+1<len&&source[i];i++){
            if(source[i]=='&#37;'&&(GetHex(source[i+1])>=0&&GetHex(source[i+2])>=0)){
                dest[destc]=GetHex(source[i+1])<<4|GetHex(source[i+2]);
                i+=2;
            }
            else if(source[i]=='+'){
                dest[destc]=' ';
            }
            else{
                dest[destc]=source[i];
            }
            destc++;
        }
        dest[destc]='\0';
    }
    
    void URLEncode(char* dest,int len,char* source){
        int destc=0,i,a,clear=0;
        for(i=0;destc+1<len&&source[i];i++){
            clear=0;
            for(a=0;nonencode[a];a++){
                if(nonencode[a]==source[i]){
                    clear=1;
                    break;
                }
            }
            if(!clear){
                if(destc+3>=len){
                    break;
                }
                dest[destc]='%';
                dest[destc+1]=hexa[source[i]/16];
                dest[destc+2]=hexa[source[i]%16];
                destc+=3;
            }
            else{
                dest[destc]=source[i];
                destc++;
            }
        }
        dest[destc]='\0';
    }
    Last edited by maxorator; 08-14-2007 at 02:05 AM.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  4. #4
    Registered User
    Join Date
    Aug 2007
    Posts
    81
    Code:
    int GetHex(char val){
        int i;
        for(i=0;hexa[i];i++){
            if(hexa[i]==val){
                if(i>15){ return i-6; }
                return i;
            }
        }
        return -1;
    }
    Definitely doesn't give you the hex value of a char....

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by keira View Post
    Code:
    int GetHex(char val){
        int i;
        for(i=0;hexa[i];i++){
            if(hexa[i]==val){
                if(i>15){ return i-6; }
                return i;
            }
        }
        return -1;
    }
    Definitely doesn't give you the hex value of a char....
    Why not - the "i-6" is there to fix up that the "abcdef" part of the string is behind the "ABCDEF" part of the string. Or am I missing something?

    --
    Mats

  6. #6
    Registered User
    Join Date
    Nov 2006
    Posts
    34
    I've done some revision and I'm capable of fully reading a line now and assigning data to my structure, and printing it out fine.

    My next problem now is I can't get it to URL encode now here is my new code, my plan is this.

    1. create a function similiar to the getline function that will read in the data from PERSONAL_TYPE structure when it reads the characters it will convert them to URL.
    2. run the converted characters through the printPersonInfo function back to the standard output
    3. run converted characters through another getline function that uses the URLdecode coding
    4. finally run converted characters through printPersonInfo again to show unencoded characters

    My problem really is now I'm having difficulty modifying the getline function to accept PERSONAL_TYPE structure, character by character. I started out with this, but am getting else without an if error, and i'm not sure how to proceed.

    Code:
    int UrlEncode(char line[], int max){ // encoding function
    	int nch = 0;
    	int c = 0;
    	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]);
    		} // end else
    		
    	 } // end while
    
                    if(c == EOF && nch == 0)
    	return EOF;
    	line[nch]= '\0';
    	return nch;
    
    }// end function


    full code
    Code:
    //
    //  File Name  : URL-encoder-decoder.c
    //
    //  Date       : August, 2007
    //
    //  Platform   : IBM PC (Windows XP)
    //
    //  Compiler   : Microsoft Visual C++ 6.0
    //
    ////////////////////////////////////////////////////////////////////////////////
    #define _CRT_SECURE_NO_DEPRECATE
    #define MAX_ARRAY_SIZE 100		// maximum array size
    
    
    #include <stdio.h>
    #include <ctype.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    typedef struct { // personal_type definition
    	char personName[MAX_ARRAY_SIZE];
    	char personAddress[MAX_ARRAY_SIZE];
    	char personPhoneNumber[MAX_ARRAY_SIZE];
    } PERSONAL_TYPE;
    
    void printPersonInfo (PERSONAL_TYPE personToPrint); //function to print information
    extern int getline(char line[], int);
    //extern int UrlEncode(char [], int);
    
    int main() {
    
    PERSONAL_TYPE personOne = {"\0", "\0", "\0"}; // empty data to pass to functions
    
    
    printf("enter your name please\n\n");
    getline(personOne.personName, MAX_ARRAY_SIZE);
    
    
    printf("\nenter your address please\n\n");
    getline(personOne.personAddress, MAX_ARRAY_SIZE);
    
    
    printf("\nenter your phone number please\n\n");
    getline(personOne.personPhoneNumber, MAX_ARRAY_SIZE);
    
    
    printPersonInfo(personOne);
    
    return 0;
    
    }
    
    //////////// read input lines////////////////////////////////
    int getline(char line[], int max) {
    int nch = 0;
    int c;
    max = max - 1; /* leave room for '\0' */
    
    while((c = getchar()) != EOF) {
    	if(c == '\n')
    		break;
    
    	if(nch < max)
    		{
    		line[nch] = c;
    		nch = nch + 1;
    		}
    	}
    
    if(c == EOF && nch == 0)
    	return EOF;
    
    line[nch] = '\0';
    return nch;
    }
    /////////////////////////encode function///////////////////////////////////
    
    
    
    void printPersonInfo(PERSONAL_TYPE personToPrint) { 
    	printf("\n==================================================================\n");
    	printf("\nNAME: %s\n\n       \nADDRESS: %s\n\n         \nPHONE NUMBER: %s\n",personToPrint.personName,
             personToPrint.personAddress, personToPrint.personPhoneNumber); // prints structures from PERSONAL_TYPE
    } // end function PrintPersonInfo
    
    
    /*  still working on this part 
    void UrlEncode(void){ // encoding function
    	int c=0;
    	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]);
    		}
    	 }
    }
    return inputPerson; // return struture inputPerson to function caller
     } // end function UrlEncode 
    
    
    
    void UrlDecode(void){ // decode function
    	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);
    	}
    } */

  7. #7
    Registered User
    Join Date
    Nov 2006
    Posts
    34
    I've gotten a lot further on the program but it's still not working properly, problems specifically

    1. the data in urlencoding I can't get it to pass the value to urlDecoding, so I've had to make due by asking the user to input their coded information to the urlDecode function

    2. the urlDecode function just doesn't apphend information properly, it doesn't matter if you type the information in encoded form or not, all it does it echo your input back to you

    encoded information is like %21 which comes back as a ! point,

    So the program mostly does what it does but not as well as I want to and this urlDecode function is stumbling me. Any ideas or suggestions?

    Code:
    ////////////////////////////////////////////////////////////////////////////////
    //
    //  File Name  : URL-encoder-decoder.c
    //
    //  Date       : August, 2007
    //
    //  Platform   : IBM PC (Windows XP)
    //
    //  Compiler   : Microsoft Visual C++ 6.0
    //
    ////////////////////////////////////////////////////////////////////////////////
    #define _CRT_SECURE_NO_DEPRECATE
    
    //compiler includes
    #include <stdio.h>
    #include <ctype.h>
    #include <stdlib.h>
    #include <string.h>
    
    //constants
    #define MAX_ARRAY_SIZE 100		// maximum array size
    
    //User defined definitions
    typedef struct {			    // personal_type definition
    	char personName[MAX_ARRAY_SIZE];
    	char personAddress[MAX_ARRAY_SIZE];
    	char personPhoneNumber[MAX_ARRAY_SIZE];
    } PERSONAL_TYPE;
    
    //function prototypes
    void printPersonInfo (PERSONAL_TYPE personToPrint); //function to print information
    extern char UrlEncode(char line[], int);			//function to URL encode input
    extern char UrlDecode(char line[], int);			//function to URL decode input
    
    
    
    //////////////////////////////////////////////////////////////////////////////// 
    // 
    //  Function Name : main 
    // 
    //  Originated    : August, 2007 
    // 
    //  Abstract      : input processing to URL encode and decode data 
    //									
    //  Parameters    : None
    // 
    //  Return Value  : error code - zero
    // 
    //  Misc. I/O     : na
    // 
    //  Revisions     : August, 2007
    // 
    ////////////////////////////////////////////////////////////////////////////////
    int main(void) {
    
    
    	PERSONAL_TYPE personOne = {"\0", "\0", "\0"}; // empty data to pass to functions
    
    	printf("\nenter your name please\n\n");		 
    	UrlEncode(personOne.personName, MAX_ARRAY_SIZE); //URL encodes user's name
    
    	printf("\n\nenter your address please\n\n");
    	UrlEncode(personOne.personAddress, MAX_ARRAY_SIZE);//URL encodes user's address
    
    	printf("\n\nenter your phone number\n\n");
    	UrlEncode(personOne.personPhoneNumber, MAX_ARRAY_SIZE); //URL encodes user's phone number
    
    	printPersonInfo(personOne); //prints the user's  unencoded information
    
    	printf("\n\nenter your coded name\n\n");
    	UrlDecode(personOne.personName, MAX_ARRAY_SIZE); //URL decodes user's name
    
    	printf("\n\nenter your coded address\n\n");
    	UrlDecode(personOne.personAddress, MAX_ARRAY_SIZE);//URL decodes user's address
    
    	printf("\n\nenter your coded phone number\n\n");
    	UrlDecode(personOne.personPhoneNumber, MAX_ARRAY_SIZE);//URL decodes user's phone number
    
    	printPersonInfo(personOne); //print's user's encoded data
    
      return 0; //return 0 indicates sucessful completion
    
    }// end main function
    
    
    //////////////////////////////////////////////////////////////////////////////// 
    // 
    //  Function Name : printPersonInfo
    // 
    //  Originated    : August, 2007
    // 
    //  Abstract      : function to print user's name, address, and phone number
    // 
    //  Parameters    : PERSONAL_TYPE
    // 
    //  Return Value  : none
    // 
    //  Misc. I/O     : na
    // 
    //  Revisions     : August, 2007
    // 
    //////////////////////////////////////////////////////////////////////////////// 
    void printPersonInfo(PERSONAL_TYPE personToPrint) { //begin function printPersonInfo
    	printf("\n==================================================================\n");
    	printf("\nNAME: %s\n\n       \nADDRESS: %s\n\n         \nPHONE NUMBER: %s\n\n",
    	personToPrint.personName, personToPrint.personAddress,
    	personToPrint.personPhoneNumber); // prints structures from PERSONAL_TYPE
    } // end function printPersonInfo
    
    
    //////////////////////////////////////////////////////////////////////////////// 
    // 
    //  Function Name : UrlEncode
    // 
    //  Originated    : August, 2007
    // 
    //  Abstract      : function to encode user input via URL coding scheme
    // 
    //  Parameters    : array, int
    // 
    //  Return Value  : none
    // 
    //  Misc. I/O     : na
    // 
    //  Revisions     : August, 2007
    // 
    //////////////////////////////////////////////////////////////////////////////// 
    char UrlEncode(char line[], int max) { // beging function UrlEncode
    	//local variables
    	int nch = 0;
    	int c;
    	char *h = "0123456789abcdef"; //pointer for hex encoding
    
    	while( (c = getchar()) != EOF ){ // scan keyboard for input
    		if(c == '\n')                // exits function if there is a newline
    			break;
    
    		if('a' <= c && c <= 'z'      // compares ASCII values a-z, A-Z, 0-9
    		|| 'A' <= c && c <= 'Z'      // -. _. / to c 
    		|| '0' <= c && c <= '9'      // puts those characters to std output
    		|| c == '-' || c == '_' || c == '.' ) // if they are encountered
    			putchar(c);				 
    		else if( c == ' ' )		    //compares c to a see if a space was  typed	
    			putchar('+');			// if it is a + is put on std output
    		else {	//begin else		// if a character  is found not matching
    			putchar('%');			// a % is put to std output, 
    			putchar(h[c >> 4]); //shift c bits 4 times to the right leaving upper bits
    			putchar(h[c & 0x0f]);//pointer then puts in corresponding hex character and puts character in
    								//shifts c bits again comparing 4 lower bits			
    		 					//pointer then puts in corresponding hex character and puts character in
    		} // end else 
    		line[nch] = c;          // line array is assigned new value in c
    		nch++;					// increase array index by 1
    
    	} // end while loop
    	
    	if(c == EOF && nch == 0)   // compare if c is EOF and is also 0
    	return EOF;				   // return EOF to caller if true
    	line[nch] = '\0';		  // apphend terminator if not
    	return nch;				  // returns array nch to caller
    } // end function Urlencode
    
    //////////////////////////////////////////////////////////////////////////////// 
    // 
    //  Function Name : UrlDecode
    // 
    //  Originated    : August, 2007
    // 
    //  Abstract      : function to decode user input via URL coding scheme
    // 
    //  Parameters    : array, int
    // 
    //  Return Value  : none
    // 
    //  Misc. I/O     : na
    // 
    //  Revisions     : August, 2007
    // 
    ////////////////////////////////////////////////////////////////////////////////
    char UrlDecode(char line[], int max) { //begin function UrlDecode
    	//local variables
    	int nch = 0;
    	int c, c1, c2;
    	while((c = getchar()) != EOF ){ //scans keyboard for input
    			if(c == '\n')			//if newline detected exit function
    			  break;
    		if( c == '%' ){				//if c is a % sign then next two
    			c1 = getchar();			// characters are automatically scanned
    			c2 = getchar();
    		 if( c1 == EOF || c2 == EOF ) // if either character is EOF exit function 
    				break; // was exit(0);
    			c1 = tolower(c1);         //ensure c1 is lowercase
    			c2 = tolower(c2);		  //ensure c2 is lowercase
    			//if c1 or c2 is not a hex digit exit function
    			if( ! isxdigit(c1) || ! isxdigit(c2) )  break; //was exit(0);
    			if( c1 <= '9' )			//if c1 is value 9 or less
    				c1 = c1 - '0';		// c1 new value is c1- '0'
    			else					// if c1 has a value greter than 9
    				c1 = c1 - 'a' + 10; // then c1 + value a + 10 is the new c1
    			if( c2 <= '9' )			//if c2 is less than 9 then c2 is equal
    				c2 = c2 - '0';      // to c2 - the value of '0'
    			else					// if c2 is greater than 9 then c2 is 
    				c2 = c2 - 'a' + 10;	// c2 - 'a' + 10
    			nch = (16 * c1 + c2);   // 16 is multiplied to c1 then c2 is added
    			putchar(nch);			// this changes the hex of c1 and c2 into ASCII
    		} else if( c == '+' )       // if the character is a + sign a space is inserted
    			putchar(' ');
    		else
    			putchar(c);				//not working properly from here down
    			line[nch] = c;
    			nch++;
    	}
    	if(c == EOF && nch == 0)
    	return EOF;
    	line[nch] = '\0';
    	return c;
    }

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > 1. the data in urlencoding I can't get it to pass the value to urlDecoding
    Like I said earlier, if you separate input from conversion, your functions become much more re-usable.

    You should be able to do this for example
    Code:
    	fgets( personOne.personName, MAX_ARRAY_SIZE, stdin );
    	printPersonInfo(personOne); // print the input name
    	UrlEncode(personOne.personName, MAX_ARRAY_SIZE);
    	printPersonInfo(personOne); // print the encoded name
    	UrlDecode(personOne.personName, MAX_ARRAY_SIZE);
    	printPersonInfo(personOne); // back to where we started
    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.

  9. #9
    Registered User
    Join Date
    Nov 2006
    Posts
    34
    I'm going to try that again Salem, I think an idea would be as you suggested, totally remove the input section from the encoding, then reintroduce it as a parameter into the code. Thank you.

  10. #10
    Registered User
    Join Date
    Nov 2006
    Posts
    34
    I got some feedback on my submission today.

    The program is suppose to handle an input string
    with multiple key/value pairs, like this:

    name=Jimmy+Dolittle&address=7816+N.+Carson+Blvd&ph one=&#37;28574%29+860-9987

    This contains the keys: name, address, and phone. Each has an
    associated value but doesn't always have to.

    1.The first step of your program that gets user input shouldn't just be
    immediately encoding the data - you should assemble a query string like
    the one above.

    2. pass that query string to a routine that will
    build up a list of key/value pairs. You would implement a function that
    would let the caller retrieve a value from the list, using the list and
    the key as parameters, and returning a string.

    I know the first part is to seperate the actual input from the encoding that's what I'm planning on doing first. I'm sort of confused on the second part though,

    "let the caller retrieve a value from the list, using the list and
    the key as parameters, and returning a string." What's that mean? Can somebody throw up psudeocode on what that sentence is saying?

    I'm also not exactly sure how to go about making a query string I would just put in the parts like

    Code:
    print("name="%s","@address="%s","@phone number="%s",person.name, person.address,person.phone);
    but I'm pretty sure that's not how it is suppose and would be unacceptable. Thanks a bunch.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Such as
    int getField ( const char *data, const char *fieldName, char *result, size_t resultlen );

    With an example call of
    Code:
    // initialised here for testing, but in your case, read from the outside world in some manner
    char data[] = "name=Jimmy+Dolittle&address=7816+N.+Carson+Blvd&ph one=%28574%29+860-9987";
    
    char result[100];
    if ( getfield( data, "name", result, sizeof result ) ) {
      // success, result should contain "Jimmy+Dolittle"
    }
    If the named field cannot be found, return false.
    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. #12
    Registered User
    Join Date
    Nov 2006
    Posts
    34

    getting closer but new problem

    I've taken the next step and removed the user's input from the encoding process. now I have a new problem. The encoder function encodes the text just fine, except it is appehending %0A which i think is the newline, and it doesn't return the encoded text back to main. So my functions to print out the encoded segments will just print what the user inputted in the first place. Any ideas?

    Code:
    ////////////////////////////////////////////////////////////////////////////////
    //
    //  File Name  :  URLCoding.c
    //
    //  Platform   : IBM PC (Windows XP)
    //
    //  Compiler   : Microsoft Visual C++ 6.0
    //
    ////////////////////////////////////////////////////////////////////////////////
    #define _CRT_SECURE_NO_DEPRECATE
    
    
    // Compiler Includes
    #include <stdio.h> 
    #include <string.h>
    #include <stdlib.h>
    
    //Constants
    #define MAX_STRING_LENGTH 100 // Maximum file name length
    #define MAX_ARRAY_SIZE 100		// maximum array size
    
    //User defined definitions struct { // PERSON_TYPE structure definition
    typedef struct {
    	char name[MAX_ARRAY_SIZE];
    	char address[MAX_ARRAY_SIZE];
    	char phone[MAX_ARRAY_SIZE];
    } PERSON_TYPE;
    
    
    //function prototypes
    
    char encode_string(string, len); // function to encode information
    
    PERSON_TYPE scanPersonByValue(void);	// function to scan person info
    
    void printPersonInfo (PERSON_TYPE personToPrint); //function to print information
    
    
    int main (void) {
    
    	//local variables
    
    	PERSON_TYPE personOne = {"<John Paul Jones>","<123 Rainbow Way>","<1-888-555-5555>"};
    
    	printPersonInfo(personOne); // prints out default array
    
    	personOne = scanPersonByValue(); //
    
    	printPersonInfo(personOne); // prints out new information user typed in
    
    	// encoded each portion of the datatype.
    	encode_string(personOne.name, (strlen(personOne.name)));
    	encode_string(personOne.address, (strlen(personOne.address)));
    	encode_string(personOne.phone, (strlen(personOne.phone)));
    
    	// this function should print each part as encoded, but it returns what the user typed in
    	printPersonInfo(personOne);
    
    
    	return 0;
    }
    
    
    PERSON_TYPE scanPersonByValue (void) {
    
        PERSON_TYPE inputPerson;
    	char buff[MAX_ARRAY_SIZE] = {"\0"};
    	
    		printf("\nenter your name:");
    		fgets(inputPerson.name, sizeof buff, stdin);
    		printf("\nenter your address:");
    		fgets(inputPerson.address,sizeof buff, stdin);
    		printf("\nenter your phone number:");
    		fgets(inputPerson.phone, sizeof buff, stdin);
    
        return inputPerson;
    } //end function scanPersonByValue
    
    
    
    void printPersonInfo (PERSON_TYPE personToPrint) { 
      
    	printf("\n==================================================================\n");
      printf("NAME: %s            \nADDRESS: %s       \nPHONE: %s\n",personToPrint.name, 
             personToPrint.address, personToPrint.phone); // prints structures from PERSON_TYPE */
    } // end function PrintpersonInfo
    
    
    //this function encodes the data passed to it using URL encoding scheme
    char encode_string(string, len)
     char	*string;
     size_t len;
     {
    	
    
    	for(;len--;string++) {
    
    		if (*string=='*' || *string=='-'
    						 || *string=='.'
    						 || '0'<=*string && *string<= '9' 
    						 || 'A'<=*string && *string<= 'Z'
    						 || 'a'<=*string && *string<='z'
    						 || *string=='_') {
    			printf("%c",*string);
    		}
    
    		else if (*string == ' ') {
    			printf("+");
    		}
    		else {
    			printf("%%%02X",*string);
    
    		}
    		
    	}
    	return *string;
    }// end function encode_string

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Yes, you need to remove the newline which fgets() appends. The FAQ has some ways to do that.

    > fgets(inputPerson.name, sizeof buff, stdin);
    This should be
    fgets(inputPerson.name, sizeof inputPerson.name, stdin);


    > char encode_string(string, len)
    > char *string;
    > size_t len;
    Why is this written in old (K&R) C rather than ANSI-C ?
    Like
    char encode_string(char *string, size_t len)

    Your function isn't returning a modified string. To do that, you need something like
    else if (*string == ' ') *string = '+';

    But because encoding changes the length of the string, makes it longer in fact, reading from one array and writing to another is much easier.
    ISTR telling you all this in your previous thread.
    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.

  14. #14
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466
    Peoples names and addresses and phone numbers don't convert to a URL. That's the problem.

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

    getting closer

    I'm getting closer, I've decided to scrap my own ideas, and implement the ideas of the smarter people in the forum here is the new code but I still have 1 issue. The function URLEncode spits out %20 for a space which, while is correct, should be '+' instead. I've spent a couple hours trying to figure out how to do it, but to no avail.

    Code:
    ////////////////////////////////////////////////////////////////////////////////
    //
    //  File Name  :  URLCoding.c
    //
    //  Platform   : IBM PC (Windows XP)
    //
    //  Compiler   : Microsoft Visual C++ 6.0
    //
    ////////////////////////////////////////////////////////////////////////////////
    #define _CRT_SECURE_NO_DEPRECATE
    
    
    // Compiler Includes
    #include <stdio.h> 
    #include <string.h>
    #include <stdlib.h>
    
    //Constants
    #define MAX_STRING_LENGTH 100 // Maximum file name length
    #define MAX_ARRAY_SIZE 100		// maximum array size
    
    const char hexa[]={"0123456789ABCDEFabcdef"};
    const char nonencode[]={"abcdefghijklmnopqrstuvwqyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_~"};
    
    
    //User defined definitions struct { // PERSON_TYPE structure definition
    typedef struct {
    	char name[MAX_ARRAY_SIZE];
    	char address[MAX_ARRAY_SIZE];
    	char phone[MAX_ARRAY_SIZE];
    } PERSON_TYPE;
    
    
    //function prototype
    
    void strip_newline( char *string, int size );
    char encode_string(char *string, size_t length); // function to encode information
    
    PERSON_TYPE scanPersonByValue(void);	// function to scan person info
    
    void printPersonInfo (PERSON_TYPE personToPrint); //function to print information
    
    void URLEncode(char* destination, int length, char* source);
    void URLDecode(char* destination, int length, char* source);
    int GetHex(char value);
    
    
    int main (void) {
    
    	//local variables
    
    	PERSON_TYPE personOne = {"<JOHN PAUL Jones>","<124 Rainbow Way>","<1-888-555-4444>"};
    	PERSON_TYPE encodedPerson = {'\0', '\0', '\0'};
    	PERSON_TYPE unencodedPerson = {'\0', '\0', '\0'};
    
    	printPersonInfo(personOne); // prints out default array
    
    	personOne = scanPersonByValue(); //
    
    	URLEncode(encodedPerson.name, sizeof personOne.name, personOne.name);
    	URLEncode(encodedPerson.address, sizeof personOne.address, personOne.address);
    	URLEncode(encodedPerson.phone, sizeof personOne.phone, personOne.phone);
    
    	printPersonInfo(encodedPerson);
    
    	// this is to test to make sure personOne is just being sent to URLDecode
    	// it isn't so URLDecode is working properly
    	personOne= scanPersonByValue();
    	printPersonInfo(personOne);
    
    	URLDecode(unencodedPerson.name, sizeof encodedPerson.name, encodedPerson.name);
    	URLDecode(unencodedPerson.address, sizeof encodedPerson.address, encodedPerson.address);
    	URLDecode(unencodedPerson.phone, sizeof encodedPerson.phone, encodedPerson.phone);
    
    	printPersonInfo(unencodedPerson);
    
    
    	return 0;
    }
    
    
    PERSON_TYPE scanPersonByValue (void) {
    
        PERSON_TYPE inputPerson;
    
    		printf("\nenter your name:");
    		fgets(inputPerson.name, sizeof inputPerson.name, stdin);
    		strip_newline(inputPerson.name, strlen(inputPerson.name));
    
    		printf("\nenter your address:");
    		fgets(inputPerson.address,sizeof inputPerson.address, stdin);
    		strip_newline(inputPerson.address, strlen(inputPerson.address));
    
    
    		printf("\nenter your phone number:");
    		fgets(inputPerson.phone, sizeof inputPerson.phone, stdin);
    		strip_newline(inputPerson.phone, strlen(inputPerson.phone));
    
    
        return inputPerson;
    } //end function scanPersonByValue
    
    
    
    void printPersonInfo (PERSON_TYPE personToPrint) { 
      
    	printf("\n==================================================================\n");
      printf("NAME: %s            \nADDRESS: %s       \nPHONE: %s\n",personToPrint.name, 
             personToPrint.address, personToPrint.phone); // prints structures from PERSON_TYPE */
    } // end function PrintpersonInfo
    
    
    void strip_newline( char *string, int size )
    {
        int i;
    
        /* remove the null terminator */
        for (  i = 0; i < size; ++i )
        {
            if ( string[i] == '\n' )
            {
                string[i] = '\0';
    
                /* we're done, so just exit the function by returning */
                return;   
            }
        }
        /* if we get all the way to here, there must not have been a newline! */
    }
    
    
    int GetHex(char value){
        int i;
        for(i=0;hexa[i];i++){
            if(hexa[i]==value){
                if(i>15){ return i-6; }
                return i;
            }
        }
        return -1;
    }
    
    void URLDecode(char* destination,int length, char* source){
        //local variables
    	int destc=0,i;
    
        for(i=0;destc+1<length&&source[i];i++){
            if(source[i]=='%'&&(GetHex(source[i+1])>=0&&GetHex(source[i+2])>=0)){
                destination[destc]=GetHex(source[i+1])<<4|GetHex(source[i+2]);
                i+=2;
            }
            else if(source[i]=='+'){
                destination[destc]=' ';
            }
            else{
                destination[destc]=source[i];
            }
            destc++;
        }
        destination[destc]='\0';
    }
    
    void URLEncode(char* destination,int length, char* source){
    	//local variables
        int destc=0;
    	int i;
    	int a;
    	int clear=0;
    
        for(i=0;destc+1<length&&source[i];i++){
            clear=0;
            for(a=0;nonencode[a];a++){
                if(nonencode[a]==source[i]){
                    clear=1;
                    break;
                }
            }
            if(!clear){
                if(destc+3>=length){
                    break;
                }
    
                destination[destc]='%';
                destination[destc+1]=hexa[source[i]/16];
                destination[destc+2]=hexa[source[i]%16];
                destc+=3;
            }
    			
            else{
                destination[destc]=source[i];
                destc++;
            }
        }
        destination[destc]='\0';
    }
    My next step is to take the encoded information and make a query string with it. Then take that URLDecode function and have the query string passed to it after it has been broken apart. Thanks for all the help

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Encode and Decode algorith for 2 to 7 bits
    By kingofpop in forum C Programming
    Replies: 2
    Last Post: 11-15-2008, 07:08 AM
  2. Interpreter.c
    By moussa in forum C Programming
    Replies: 4
    Last Post: 05-28-2008, 05:59 PM
  3. Url query encoding/decoding
    By Niara in forum Networking/Device Communication
    Replies: 6
    Last Post: 04-25-2007, 03:30 PM
  4. File I/O Encode & Decode with XOR
    By DarrenY in forum C# Programming
    Replies: 2
    Last Post: 04-12-2007, 04:31 AM
  5. suggestions : encode / decode header + documentation
    By gamer in forum C++ Programming
    Replies: 4
    Last Post: 11-21-2004, 05:17 AM