Encoding URL

Hello.
I'm trying to port this code:
char *urlencode(char *c)
{
    
    char escaped[2000] = {0};
	char *buffer;
    int max = strlen(c);
    for(int i=0; i<max; i++)
    {
        if ( (48 <= c[i] && c[i] <= 57) ||//0-9
             (65 <= c[i] && c[i] <= 90) ||//abc...xyz
             (97 <= c[i] && c[i] <= 122) || //ABC...XYZ
             (c[i]=='~' || c[i]=='!' || c[i]=='*' || c[i]=='(' || c[i]==')' || c[i]=='\'')
        )
        {
			
            strncat(escaped, (const char*)c[i],1);
        }
        else
        {

			sprintf(buffer, "%x", c[i]);
            strncat(escaped,"%",2);
            strncat(escaped,buffer,1 );//converts char 255 to string "ff"
        }
    }
    return escaped;
}

Open in new window


is crashing on attempt... I know it has something to do with the way I'm appending data to "escaped" but I don't know how to modify it to work properly.

I'm attempting to mimic the following script (which works perfectly):
string urlencode(const string &c)
{
    
    string escaped="";
    int max = c.length();
    for(int i=0; i<max; i++)
    {
        if ( (48 <= c[i] && c[i] <= 57) ||//0-9
             (65 <= c[i] && c[i] <= 90) ||//abc...xyz
             (97 <= c[i] && c[i] <= 122) || //ABC...XYZ
             (c[i]=='~' || c[i]=='!' || c[i]=='*' || c[i]=='(' || c[i]==')' || c[i]=='\'')
        )
        {
            escaped.append( &c[i], 1);
        }
        else
        {
            escaped.append("%");
            escaped.append( char2hex(c[i]) );//converts char 255 to string "ff"
        }
    }
    return escaped;
}

string char2hex( char dec )
{
    char dig1 = (dec&0xF0)>>4;
    char dig2 = (dec&0x0F);
    if ( 0<= dig1 && dig1<= 9) dig1+=48;    //0,48inascii
    if (10<= dig1 && dig1<=15) dig1+=97-10; //a,97inascii
    if ( 0<= dig2 && dig2<= 9) dig2+=48;
    if (10<= dig2 && dig2<=15) dig2+=97-10;

    string r;
    r.append( &dig1, 1);
    r.append( &dig2, 1);
    return r;
}

Open in new window


but I want  to avoid using strings in my version of it.

so basically I need to know how to properly append data to "escaped" in the given context.

thank you
JoeD77Asked:
Who is Participating?
 
phoffricConnect With a Mentor Commented:
I'm back.
>> No I mean it still crashed.

Ok, so there was more than one problem.
So, I took another look. This time I built and ran the program using both the string and char * version.

OUTPUT:

address=123 #5 M&M Street
address=123%20%235%20M%26M%20Street
address=123%20%235%20M%26M%20Street

#include <iostream>
#include <string.h>
using namespace std;

char *urlencode(char *c)  
{
    static char escaped[2000] = {0};  
    char buffer[10];
    int max = strlen(c);  
    for(int i=0; i<max; i++)  
    {  
        if ( (48 <= c[i] && c[i] <= 57) ||//0-9  
            (65 <= c[i] && c[i] <= 90) ||//abc...xyz  
            (97 <= c[i] && c[i] <= 122) || //ABC...XYZ  
            (c[i]=='~' || c[i]=='!' || c[i]=='*' || c[i]=='(' || c[i]==')' || c[i]=='\'')  
            )  
        {   char tmp[2] = {c[i],0};
            strcat(escaped, tmp);  
        }  
        else  
        {
            sprintf(buffer, "%x", c[i]);  
            strncat(escaped,"%",2);  
            strncat(escaped,buffer,strlen(buffer) );//converts char 255 to string "ff"  
        }
    }
    return escaped;  
}

string char2hex( char dec )  
{  
    char dig1 = (dec&0xF0)>>4;  
    char dig2 = (dec&0x0F);  
    if ( 0<= dig1 && dig1<= 9) dig1+=48;    //0,48inascii  
    if (10<= dig1 && dig1<=15) dig1+=97-10; //a,97inascii  
    if ( 0<= dig2 && dig2<= 9) dig2+=48;  
    if (10<= dig2 && dig2<=15) dig2+=97-10;  

    string r;  
    r.append( &dig1, 1);  
    r.append( &dig2, 1);  
    return r;  
}

string urlencode2(const string &c)  
{
    string escaped="";  
    int max = c.length();  
    for(int i=0; i<max; i++)  
    {  
        if ( (48 <= c[i] && c[i] <= 57) ||//0-9  
            (65 <= c[i] && c[i] <= 90) ||//abc...xyz  
            (97 <= c[i] && c[i] <= 122) || //ABC...XYZ  
            (c[i]=='~' || c[i]=='!' || c[i]=='*' || c[i]=='(' || c[i]==')' || c[i]=='\'')  
            )  
        {  
            escaped.append( &c[i], 1);  
        }  
        else  
        {  
            escaped.append("%");  
            escaped.append( char2hex(c[i]) );//converts char 255 to string "ff"  
        }  
    }  
    return escaped;  
}  


int main()  
{  
    char *address = "123 #5 M&M Street";  
    cout << "address=" << address << endl;  
    cout << "address=" << urlencode2(address).c_str() <<endl;  
    cout << "address=" << urlencode (address) <<endl;  
}

Open in new window

0
 
phoffricCommented:
escape is a local variable that is no longer valid when the function returns. If single threaded, you can do this:
   static char escaped[2000] = {0};

Otherwise, you should define escape from the caller and pass it in as an argument.

0
 
JoeD77Author Commented:
Yes, sorry, I left out the main function of the code:
int main()
{
    char *address = "123 #5 M&M Street";
    cout << "address=" << address << endl;
    cout << "address=" << urlencode(address) <<endl;
}

Open in new window

0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
phoffricCommented:
Does it still crash when adding static?
0
 
jkrCommented:
Why not simply using 'InternetCanonicalizeUrl()' (http://msdn.microsoft.com/en-us/library/aa384342(VS.85).aspx) for that purpose instead of rolling your own solution?
0
 
JoeD77Author Commented:
@ phoffric yes it did
@ jkr - because I read that ICU() will not work when the data you're trying to encode is not a valid URL to begin with. I need to URL encode a string, then append it to the URL afterwards. Is there a way to use ICU() to a string that does not contain a URL?
0
 
phoffricCommented:
Very good. Glad to be of assistance.
0
 
JoeD77Author Commented:
No I mean it still crashed.

sorry for the confusion.

here's the current code:
int main()
{
    char *address = "123 #5 M&M Street";
    cout << "address=" << address << endl;
    cout << "address=" << urlencode(address) <<endl;
}

char *urlencode(char *c)
{
    
    static char escaped[2000] = {0};
	char *buffer;
    int max = strlen(c);
    for(int i=0; i<max; i++)
    {
        if ( (48 <= c[i] && c[i] <= 57) ||//0-9
             (65 <= c[i] && c[i] <= 90) ||//abc...xyz
             (97 <= c[i] && c[i] <= 122) || //ABC...XYZ
             (c[i]=='~' || c[i]=='!' || c[i]=='*' || c[i]=='(' || c[i]==')' || c[i]=='\'')
        )
        {
			
            strncat(escaped, (const char*)c[i],1);
        }
        else
        {

			sprintf(buffer, "%x", c[i]);
            strncat(escaped,"%",2);
            strncat(escaped,buffer,strlen(buffer) );//converts char 255 to string "ff"
        }
    }
    return escaped;
}

Open in new window


still something wrong with the concatenation I believe
0
 
Dave BaldwinFixer of ProblemsCommented:
0
 
jkrCommented:
>>@ jkr - because I read that ICU() will not work when the data you're trying
>>to encode is not a valid URL to begin with. I need to URL encode a string,
>>then append it to the URL afterwards. Is there a way to use ICU() to a
>>string that does not contain a URL?

Why don't you just build the whole URL with the data you have and pas it to that function afterwards? Since it is to end up as an URL anyway, I'd at leat try that ;o)
0
 
JoeD77Author Commented:
hah I guess I was overthinking (or underthinking*) that jkr.

do you have a working example?
char *url = "http://microsoft.com/website/mywebpage/";
	char buffer[50] = {0};
	DWORD sz;
	InternetCanonicalizeUrl(url, buffer, &sz, 0);
	cout << buffer;

Open in new window

has a blank output?
0
 
ozoCommented:
char *urlencode(char *c)
{

    static char escaped[2000] = {0};
    char *buffer=(char*)malloc(2000);
    escaped[0]='\0';
    int max = strlen(c);
    for(int i=0; i<max; i++)
    {
        if ( (48 <= c[i] && c[i] <= 57) ||//0-9                                             
             (65 <= c[i] && c[i] <= 90) ||//abc...xyz                                       
             (97 <= c[i] && c[i] <= 122) || //ABC...XYZ                                     
             (c[i]=='~' || c[i]=='!' || c[i]=='*' || c[i]=='(' || c[i]==')' || c[i]=='\'')
        )
        {

            strncat(escaped, (const char*)&c[i],1);
        }
        else
        {

            sprintf(buffer, "%x", c[i]);
            strncat(escaped,"%",2);
            strncat(escaped,buffer,strlen(buffer) );//converts char 255 to string "ff"      
        }
    }
    return escaped;
}

Open in new window

0
 
JoeD77Author Commented:
Thank you works perfectly.
0
 
phoffricCommented:
Very good. Glad to be of assistance again :)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.