[ sscanf'ing e.g. s1=stringvalue&offset=123 limiting s1 size ]
I have tried this
If I do this then reading offset will not work
It should work, and does for me.
Och, silly me. You must've meant *if the first (string) value exceeds
the limit* the &offset= portion does not match, because only part of
the first value was scanned and "converted". Three approaches,
assuming you want to silently truncate (ignore) any excess:
1) Break the string into pieces with strtok, or <nonstandard> strtok_r
if you need thread-safe or callers (or callees) might use strtok, and
sscanf each piece; but strtok[_r] modifies the string which is not
guaranteed allowed for a getenv() value so you should duplicate it:
char * data = /* nonstd or eq */ strdup (getenv ("QUERY_STRING"));
char * tok; char s1 [10]; long n;
if( ! data ) ERROR;
tok = strtok (data, "&"); if( !tok ) ERROR_QS_EMPTY;
if( sscanf (tok /* or data */, "s1=%9[^&]", s1) != 1 ) ERROR;
tok = strtok (NULL, "&"); if( !tok ) ERROR_NO_AMPERSAND;
if( sscanf (tok, "offset=%ld", &n1) ERROR;
/* optionally check ! strtok (NULL, "&") */
2) Find the &'s nondestructively with strchr, and do the string
handling and (some) parsing yourself:
char * data = getenv ("QUERY_STRING");
char * next; char s1 [10]; long n; int fits;
if( ! data ) ERROR;
next = strchr (data, '&');
if( ! next ) ERROR_NO_AMPERSAND;
if( strncmp (data, "s1=", 3) != 0 ) ERROR;
fits = min (next-data-3, sizeof s1 -1);
if( ! fits ) ERROR_S1_EMPTY;
memcpy (s1, data+3, fits); s1[fits] = '\0';
if( sscanf (next+1, "offset=%ld", &n) != 1) ERROR;
or for the last, a tiny bit more efficient:
if( strncmp (next+1, "offset=", 7) != 0 ) ERROR;
n = strtol (next+1+7, NULL, 10);
3) If you really want to use sscanf, you must use two calls to allow
for the "overflow" conversion failing in the (presumably normal)
nonoverflow case, but they can be in one statement:
char * data = getenv ("QUERY_STRING");
char s1 [10]; long n; int used;
if( ! data ) ERROR;
if( sscanf (data, "s1=%9[^&]%*[^&]%n", s1, &used) != 1
|| sscanf (data+used, "&offset=%ld", &n) != 1 ) ERROR;
If you want to detect overflow and give a specific error, or use
something other than the truncated value, it's a little more
complicated; if you don't see how, ask more specifically.
- David.Thompson1 at worldnet.att.net