Reputation: 183
I need to parse a string in c with the following format "foo=%d", I need to check that the format is correct and read the int value.
My initial code was:
int foo_set = 0;
int foo;
if (sscanf(text, "foo=%d", &foo) == 1)
foo_set = 1;
But the code should refuse input such as "foo=5$%£". Would this code work?
int foo_set = 0;
int foo;
char control;
if (sscanf(text, "foo=%d%c", &foo, &control) == 1)
foo_set = 1;
Using the control
character the code check that there are no extra input.
Are there a better/more correct way to do this?
Thanks
Upvotes: 3
Views: 1663
Reputation: 122011
Use the %n
format specifier to determine where processing ended and check it matches the length of the string:
const char* text = "foo=4d";
int pos;
int foo;
if (sscanf(text, "foo=%d%n", &foo, &pos) == 1 &&
pos == strlen(text))
{
/* Valid as all of text consumed. */
}
Description for format specifier n
from the C99 standard:
No input is consumed. The corresponding argument shall be a pointer to signed integer into which is to be written the number of characters read from the input stream so far by this call to the fscanf function. Execution of a %n directive does not increment the assignment count returned at the completion of execution of the fscanf function. No argument is converted, but one is consumed. If the conversion specification includes an assignment suppressing character or a field width, the behavior is undefined.
See demo at https://ideone.com/d1rhPf .
Upvotes: 10