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?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
phoffricCommented:
Does it still crash when adding static?
0
Amazon Web Services

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

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
phoffricCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.