using scanf to read a string and an int separated by /
You only need to run the following program:
#include <stdio.h>
int main (void) {
char str[20] = {'\0'};
int count, num = 42;
count = sscanf ("hello/17", "%s/%d", str, &num);
printf ("String was '%s'\n", str);
printf ("Number was %d\n", num);
printf ("Count was %d\n", count);
return 0;
}
to see why this is happening. The output is:
String was 'hello/17'
Number was 42
Count was 1
The reason has to do with the %s
format specifier. From C99 7.19.6.2 The fscanf function
(largely unchanged in C11, and the italics are mine):
s
: matches a sequence of non-white-space characters.
Since /
is not white space, it gets included in the string bit, as does the 17
for the same reason. That's also indicated by the fact that sscanf
returns 1
, meaning that only one item was scanned.
What you'll then be looking for is something that scans any characters other than /
into the string (including white space). The same section of the standard helps out there as well:
[
: matches a nonempty sequence of characters from a set of expected characters (the scanset). The conversion specifier includes all subsequent characters in the format string, up to and including the matching right bracket (]). The characters between the brackets (the scanlist) compose the scanset, unless the character after the left bracket is a circumflex (^), in which case the scanset contains all characters that do not appear in the scanlist between the circumflex and the right bracket.
In other words, something like:
#include <stdio.h>
int main (void) {
char str[20] = {'\0'};
int count, num = 42;
count = sscanf ("hello/17", "%[^/]/%d", str, &num);
printf ("String was '%s'\n", str);
printf ("Number was %d\n", num);
printf ("Count was %d\n", count);
return 0;
}
which gives you:
String was 'hello'
Number was 17
Count was 2
One other piece of advice: never ever use scanf
with an unbounded %s
or %[
; you're asking for a buffer overflow attack. If you want a robust user input function, see this answer.
Once you have it in as a string, you can sscanf
it to your heart's content without worrying about buffer overflow (since you've limited the size on input).
scanf
awaits a whitespace terminated string when it tries to read %s
.
Try to specify the forbidden character set directly:
scanf("%19[^/]/%d", str, &num);
You can read more about the formating codes here