Click to See Complete Forum and Search --> : cgi in c


TheLawnGnome
01-25-2001, 06:04 AM
hey i'm making a cgi script in c and i'm havin a little trouble decoding the hex for the misc. characters. take a look at my function.

char *decode(char *the_string)
{
int x = 0;

while (the_string[x])
{
switch (the_string[x])
{
case '+':
the_string[x] = ' ';
break;


case '%':
// this is the part i need help on
// the string will be something like "hi how are you%3F"
// where as 3F is the hex for a "?"
// so i need to be able to change "%3F" to "?" in the middle
// of a string.

}

x++;

}
return the_string;
}

Whipping Boy
01-25-2001, 05:58 PM
You may want to go to http://www.gnu.org and download and use cgicc. It's the C++ equivalent of CGI.pm (I'm not sure if it works with C or if it has certain C++-specific features).

------------------
Kurt Weber
Shell scripts? Shell scripts? We don't NEED no stinkin' shell scripts!
White, heterosexual, middle-class, and proud!
I've never understood why Bill Gates would name his company after his penis

Stuka
01-26-2001, 01:43 AM
I forget - is there a guaranteed length on the hex string? It oughta always be 2 characters, right? And that hex string is the ASCII value of the character, isn't it? If so, just convert the hex string following the % sign to a char variable, place it at the location you read the % sign from, then eat the next two characters...you might need a separate var to use as a 'write pointer' if you will, to facilitate eliminating the spaces w/o screwing up your 'read pointer' (the x var).

TheLinuxDuck
01-26-2001, 07:44 PM
LawnGnome:

I know that the CGI libraries do this sort of thing for you automagically, but nonetheless, that isn't always an option.

At any rate, here's my attempt at converting the hex values and +'s to a normal string.

I am assuming that the length of the hex is 2, but it is changeable in the source.

#include <stdio.h> // printf
#include <string.h> // strcat, strlen
#include <ctype.h> // toupper

#define HEX_LENGTH 2

void decode(char *new_string,char *old_string, int maxlength);

int main(void)
{
char data[25]="Hi%2c+how+are+you%3f";
char new[25];

decode(new,data,strlen(data));
printf("old: %s\nnew: %s\n",data,new);
return 1;
}

void decode(char *new_string,char *old_string, int maxlength)
{
//
// We parse through the old_string, one char at a time, building up
// new_string as we go. temp is used to append a single char to
// new_string. I've found this to be an easy and effective means to
// deal with single chars like this
//
char temp[2]={0};
//
// i is used for looping through whatever HEX_LENGTH is set to, and counter
// just makes sure that we don't exceed our allowed string length, g is a
// temp variable used to convert the hex character to a real value
//
int i,counter=0;
int g;
//
// make sure that new_string is empty
//
new_string[0]=0;
//
// I find the easiest way to loop through a string is to use the passed
// pointer, assuming you don't need to rewind. We just ensure that we
// haven't hit the end of the string yet (by checking for '\0', and that
// the built string doesn't exceed our maximum length
//
while(*old_string!='\0' && counter<maxlength) {
//
// good old switch... :) test each character individually
//
switch(*old_string) {
case '+': // simply convert to a space
temp[0]=' ';
break;
case '%': // hex coming up
temp[0]=0; // reset our temp char to 0
//
// This loop simply looks through the old_string character by
// character, until HEX_LENGTH is found.
//
for(i=0;i<HEX_LENGTH;++i) {
++old_string; // move to our next position (first hex char)
//
// uppercasing it just makes sure that we don't have to check
// for upper and lower case when converting the number
//
(*old_string)=toupper(*old_string);
//
// If the character we're on in greater than the number 57 (or
// the number 9), we know that it's going to be a A-F, which means
// 10-15, so we subtract 55 (since A = 65). Otherwise, we simply
// subtract 48 (since 0=48) to make our character be the actual
// value we want to deal with.
//
g=(*old_string)>57?(*old_string)-55 :(*old_string)-48;
//
// Nest, we want to multiply the number by (16*n), n being the
// position of the hex we are at. Of a 2 place hex number, 0 would
// mean 16*1, and 1 would mean 1. Of a 4 place hex number, 0 would
// mean 16*3, 1 would mean 16*2, 1 would mean 16*1, and 2 would mean
// 1. So, if we're on the last position of the hex, we return 1,
// otherwise, we subtract our current position from the hex length
// and multiply it by 16.
//
g*=(i==(HEX_LENGTH-1))?1 :((HEX_LENGTH-1)-i)*16;
//
// Add the current position to our number we're building
//
temp[0]+=g;
}
break;
default:
temp[0]=(*old_string);
break;
}
//
// append the new character to our new_string, and increment our position
// counter, and the position of the old_string that we're on
//
strcat(new_string,temp);
++old_string;
++counter;
}
}



This should work, but I only tested it with the sample data in the code. If there's something missing and you add it, or I need to fix, let me know.. :)

------------------
TheLinuxDuck
I have a belly button.
:wq

[This message has been edited by TheLinuxDuck (edited 26 January 2001).]