Reputation: 14882
I'm trying to parse a URL query string in C and I don't see how to do it elegantly. Any hints or suggestions would be greatly appreciated:
static void readParams(char * string, char * param, char * value) {
char arg[100] = {0}; // Not elegant, brittle
char value2[1024] = {0};
sscanf(string, "%[^=]=%s", arg, value2);
strcpy(param, arg);
strcpy(value, value2);
}
char * contents = "username=ted&age=25";
char * splitted = strtok (contents,"&");
char * username;
char * age;
while (splitted != NULL)
{
char param[100]; // Not elegant, brittle
char value[100];
char * t_str = strdup(splitted);
readParams(t_str, param, value);
if (strcmp(param, "username") == 0) {
username = strdup(value);
}
if (strcmp(param, "age") == 0) {
age = strdup(value); // This is a string, can do atoi
}
splitted = strtok (NULL, "&");
}
The problem I kept on having is that because of the strtok
function anything that was seemed more intelligent to do before the last strtok
function seemed to break the while loop.
Upvotes: 7
Views: 8225
Reputation: 9847
I do:
char querystring[]="a=1&b&c=3&d=&meh=5";
int pc=0;
char *tok;
char *otok;
for(tok=strtok(querystring,"&");tok!=NULL;tok=strtok(tok,"&")) {
pc++;
otok=tok+strlen(tok)+1;
tok=strtok(tok,"=");
fprintf(stderr,"param%d: %s ",pc,tok);
tok=strtok(NULL,"=");
fprintf(stderr,"value%d: %s\n",pc,tok);
tok=otok;
};
remember that strtok destroys the original so before this just make a copy of the querystring.
Upvotes: 2
Reputation: 8887
You either need to tailor complex and effective parser or settle with libraries that will do it for you.
uriparser should provide all you need (plus it supports unicode).
Upvotes: 2
Reputation: 35225
Assumptions is not a bad thing, in general, and especially in fast, robust and protective code (consider, for example, that your input string have invalid format).
To reach most elastic code however, you need to manually allocate (and deallocate after usage!) memory for strings, the size of which should be to total lenght of an input string (one more time where reasonable limit is a must), since it's unknown (in general) how long is param and value string parts.
Upvotes: 0
Reputation: 16389
In general strtok breaks the source string for use by some other functions. Here is a bare bones example of using strtok to tokenize a string
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define MX_SPLIT 128
char **split( char **result, char *working, const char *src, const char *delim)
{
int i;
strcpy(working, src); // working will get chppped up instead of src
char *p=strtok(working, delim);
for(i=0; p!=NULL && i < (MX_SPLIT -1); i++, p=strtok(NULL, delim) )
{
result[i]=p;
result[i+1]=NULL; // mark the end of result array
}
return result;
}
void foo(const char *somestring)
{
int i=0;
char *result[MX_SPLIT]={NULL};
char working[256]={0x0}; // assume somestring is never bigger than 256 - a weak assumption
char mydelim[]="!@#$%^&*()_-";
split(result, working, somestring, mydelim);
while(result[i]!=NULL)
printf("token # %d=%s\n", i, result[i]);
}
Upvotes: 1